Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

byval argument of C ABI function passed to Rust ABI function has insufficient alignment #122211

Closed
erikdesjardins opened this issue Mar 8, 2024 · 2 comments · Fixed by #122212
Labels
A-FFI Area: Foreign function interface (FFI) C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@erikdesjardins
Copy link
Contributor

I tried this code:

#[repr(align(16))]
pub struct HighAlign {
    x: u128,
    y: u128,
}

extern { fn consume(x: &HighAlign); }

#[no_mangle]
pub unsafe extern "C" fn takes_aligned(x: HighAlign) {
    consume(&x);
}

I expected to see this happen: Alignment requirements are upheld.

Instead, this happened: https://godbolt.org/z/ej65d5hsv

define void @takes_aligned(ptr byval(%HighAlign) align 4 %x) unnamed_addr #0 {
  call void @consume(ptr align 16 %x)
  ret void
}

%x is clearly not align 16 as we indicate. This is unsound.

@rustbot label I-unsound A-ffi


This issue is somewhat similar to #80127. The fix for that issue, #112157, made this problem worse by causing Rust and byval alignments to differ in more cases. (That change is correct, because the Rust and byval alignment must differ to satisfy the ABI. It just uncovered this issue in more cases.)

This is also similar to #112480. However, unlike that one, this issue is practical (and easy) to fix. byval pointers are not exposed to Rust code, so we can just make a copy of the argument into a higher-aligned alloca, without breaking Rust semantics.

In fact, we already do this in the reverse situation, when the Rust alignment is lower than the byval alignment (https://godbolt.org/z/Ksxoo3aja):

#[repr(packed)]
pub struct LowAlign {
    x: u128,
    y: u128,
    z: u128,
}

extern "C" { fn consume(x: LowAlign); }

#[no_mangle]
pub unsafe fn call_low_align(x: LowAlign) {
    consume(x);
}
define void @call_low_align(ptr align 1 %x) unnamed_addr #0 {
  %0 = alloca %LowAlign, align 4
  call void @llvm.memcpy.p0.p0.i32(ptr align 4 %0, ptr align 1 %x, i32 48, i1 false)
  call void @consume(ptr byval(%LowAlign) align 4 %0)
  ret void
}

Meta

rustc --version --verbose:

rustc 1.76.0 (07dca489a 2024-02-04)
binary: rustc
commit-hash: 07dca489ac2d933c78d3c5158e3f43beefeb02ce
commit-date: 2024-02-04
host: x86_64-unknown-linux-gnu
release: 1.76.0
LLVM version: 17.0.6
Compiler returned: 0
@erikdesjardins erikdesjardins added the C-bug Category: This is a bug. label Mar 8, 2024
@rustbot rustbot added needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. A-FFI Area: Foreign function interface (FFI) I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Mar 8, 2024
@erikdesjardins
Copy link
Contributor Author

I will open a fix for this shortly.

@erikdesjardins erikdesjardins changed the title byval argument of extern "C" function passed to extern "Rust" function has insufficient alignment byval argument of C-ABI function passed to Rust-ABI function has insufficient alignment Mar 8, 2024
@erikdesjardins erikdesjardins changed the title byval argument of C-ABI function passed to Rust-ABI function has insufficient alignment byval argument of C ABI function passed to Rust ABI function has insufficient alignment Mar 8, 2024
@Noratrieb Noratrieb added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Mar 9, 2024
@apiraino
Copy link
Contributor

WG-prioritization assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-high

@rustbot rustbot added P-high High priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Mar 11, 2024
@bors bors closed this as completed in 722514f Mar 15, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Mar 15, 2024
Rollup merge of rust-lang#122212 - erikdesjardins:byval-align2, r=wesleywiser

Copy byval argument to alloca if alignment is insufficient

Fixes rust-lang#122211

"Ignore whitespace" recommended.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-FFI Area: Foreign function interface (FFI) C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants