Skip to content

cranelift-jit: assert that relocations stay within their definition - #14788

Open
ilyas-mallah wants to merge 6 commits into
bytecodealliance:mainfrom
ilyas-mallah:cranelift-jit-reloc-checks
Open

ilyas-mallah wants to merge 6 commits into
bytecodealliance:mainfrom
ilyas-mallah:cranelift-jit-reloc-checks

Conversation

@ilyas-mallah

@ilyas-mallah ilyas-mallah commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

CompiledBlob::perform_relocations writes each relocation through a raw pointer at its offset into the definition. The only check is a debug_assert that the offset is below the size. Release builds have no check, and the debug one ignores the bytes the write covers. The offsets come from safe APIs (DataDescription::write_data_addr and write_function_addr, and the relocs of define_function_bytes), so safe code can make finalize_definitions write past a definition. In a release build, an Abs8 relocation at offset 4 of an 8-byte data object overwrote the first 4 bytes of the next object.

perform_relocations now asserts, in release builds too, that each relocation's full span lies within its definition before it writes. The span comes from a new Reloc::patched_len, an exhaustive match so a new relocation kind has to state its width. For every kind perform_relocations handles, that width is the number of bytes it already writes there, so a relocation it applied in bounds before still passes. The new tests expect the panic from finalize_definitions and fail on main.

@ilyas-mallah
ilyas-mallah requested a review from a team as a code owner October 16, 2026 19:05
@ilyas-mallah
ilyas-mallah requested review from cfallin and removed request for a team October 16, 2026 19:05
@bjorn3

bjorn3 commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Panic makes sense to me (perhaps a debug assertion? this can't happen without a bug in cranelift-codegen, so I'm not sure how much benefit there is to unconditionally checking it). And I think the check could be done inside the loop that processes the relocations right before applying them instead of iterating a second time.

Comment thread cranelift/jit/src/compiled_blob.rs Outdated
@ilyas-mallah ilyas-mallah changed the title cranelift-jit: reject relocations that patch bytes outside their definition cranelift-jit: assert that relocations stay within their definition Oct 16, 2026
@ilyas-mallah

Copy link
Copy Markdown
Contributor Author

Panic makes sense to me (perhaps a debug assertion? this can't happen without a bug in cranelift-codegen, so I'm not sure how much benefit there is to unconditionally checking it). And I think the check could be done inside the loop that processes the relocations right before applying them instead of iterating a second time.

Made it a panic, checked in the relocation loop right before each write. I kept it in release builds because the offsets don't only come from cranelift-codegen. DataDescription::write_data_addr and define_function_bytes take them from the caller in safe code, so a debug assertion would still let a release build write past a definition. It's one compare per relocation.

@github-actions github-actions Bot added the cranelift Issues related to the Cranelift code generator label Oct 16, 2026
Comment thread cranelift/codegen/src/binemit/mod.rs Outdated
…equence

The linker rewrites the lea and call together when it relaxes the sequence, so patched_len covers 12 bytes from the displacement. The jit bounds test gains a case for it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cranelift Issues related to the Cranelift code generator

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants