miri: enforce proper types for c-variadic arguments in shims - #161734
Conversation
|
Some changes occurred to the CTFE / Miri interpreter cc @rust-lang/miri These commits modify the If this was unintentional then you should revert the changes before this PR is merged.
cc @rust-lang/miri Some changes occurred to the CTFE machinery Some changes occurred to the CTFE / Miri interpreter |
|
r? @mejrs rustbot has assigned @mejrs. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
|
r? @saethlin |
8cec627 to
888931c
Compare
This comment was marked as resolved.
This comment was marked as resolved.
3a365e2 to
1b22718
Compare
|
@bors try jobs=aux |
miri: enforce proper types for c-variadic arguments in shims try-job: *aux*
This comment has been minimized.
This comment has been minimized.
1b22718 to
329d83d
Compare
This comment has been minimized.
This comment has been minimized.
329d83d to
16e8469
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
16e8469 to
158f6f9
Compare
|
r? @oli-obk |
|
|
|
@bors r+ rollup |
miri: enforce proper types for c-variadic arguments in shims This adds proper type checks for c-variadic argument handling in Miri shims. So far we would have ICEd for many type mismatches since the innards of the interpreter generally assume that things are well-typed. The checks we are using are the same as for [`next_arg`](https://doc.rust-lang.org/nightly/std/ffi/struct.VaList.html#method.next_arg). This uncovered some interesting points: - We should accept `&mut` as equivalent to `*mut`. We don't allow `&mut` as a type in `next_arg` but we do allow it for c-variadic calls, so this change also affects a bit more code in const-eval (if the caller passes an `&mut` and the callee expects a `*mut`). Even CFI is okay with treating `&mut` and `*mut` as equivalent so this should be fine. Cc @folkertdev - Some places in the standard library futex handling used types for their variadic arguments that are not quite correct according to these rules. I fixed those. Cc @m-ou-se - One variadic function takes pointers to `libc::timespec`. A program with a libc dependency has two copies of libc (one in the sysroot, and the normal dependency). When Miri looks up the expected argument type, it picks one of them, leading to Miri seeing a type mismatch when there is a call using the other copy. C generally considers two copies of the same type to be identical, so I implemented logic that does the same: two `repr(C)` types are "identical" if the names of the types, and the names and types of all fields, are identical. I then also used that logic for the normal ABI checks, where it will also help since we had similar trouble there in the past (that we had to find other work-arounds for).
…uwer Rollup of 5 pull requests Successful merges: - #162470 (Subtree sync for rustc_codegen_cranelift) - #161734 (miri: enforce proper types for c-variadic arguments in shims) - #161821 (Add missing option to `-Zself-profile-event` help message as well as information about what the default options are) - #162453 (Minimize `DiagCtxt` methods) - #162528 (Add a mention to docs about promoting and demoting platform support)
Rollup merge of #161734 - RalfJung:c-variadic-types, r=oli-obk miri: enforce proper types for c-variadic arguments in shims This adds proper type checks for c-variadic argument handling in Miri shims. So far we would have ICEd for many type mismatches since the innards of the interpreter generally assume that things are well-typed. The checks we are using are the same as for [`next_arg`](https://doc.rust-lang.org/nightly/std/ffi/struct.VaList.html#method.next_arg). This uncovered some interesting points: - We should accept `&mut` as equivalent to `*mut`. We don't allow `&mut` as a type in `next_arg` but we do allow it for c-variadic calls, so this change also affects a bit more code in const-eval (if the caller passes an `&mut` and the callee expects a `*mut`). Even CFI is okay with treating `&mut` and `*mut` as equivalent so this should be fine. Cc @folkertdev - Some places in the standard library futex handling used types for their variadic arguments that are not quite correct according to these rules. I fixed those. Cc @m-ou-se - One variadic function takes pointers to `libc::timespec`. A program with a libc dependency has two copies of libc (one in the sysroot, and the normal dependency). When Miri looks up the expected argument type, it picks one of them, leading to Miri seeing a type mismatch when there is a call using the other copy. C generally considers two copies of the same type to be identical, so I implemented logic that does the same: two `repr(C)` types are "identical" if the names of the types, and the names and types of all fields, are identical. I then also used that logic for the normal ABI checks, where it will also help since we had similar trouble there in the past (that we had to find other work-arounds for).
…uwer Rollup of 5 pull requests Successful merges: - rust-lang/rust#162470 (Subtree sync for rustc_codegen_cranelift) - rust-lang/rust#161734 (miri: enforce proper types for c-variadic arguments in shims) - rust-lang/rust#161821 (Add missing option to `-Zself-profile-event` help message as well as information about what the default options are) - rust-lang/rust#162453 (Minimize `DiagCtxt` methods) - rust-lang/rust#162528 (Add a mention to docs about promoting and demoting platform support)
The nightly Miri from 2026-09-09 (rust-lang/rust#161734) type-checks c-variadic arguments in its shims, and rustix 1.1.4's libc-backend futex wrapper passes the lock word as `*const AtomicU32` where the `syscall` shim expects `*mut u32`. That fails the `c_abi_miri` test whenever an engine mutex is contended. Real Linux builds keep the futex path; Miri takes the yield-based park that every other Unix already uses. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This adds proper type checks for c-variadic argument handling in Miri shims. So far we would have ICEd for many type mismatches since the innards of the interpreter generally assume that things are well-typed. The checks we are using are the same as for
next_arg.This uncovered some interesting points:
&mutas equivalent to*mut. We don't allow&mutas a type innext_argbut we do allow it for c-variadic calls, so this change also affects a bit more code in const-eval (if the caller passes an&mutand the callee expects a*mut). Even CFI is okay with treating&mutand*mutas equivalent so this should be fine. Cc @folkertdevlibc::timespec. A program with a libc dependency has two copies of libc (one in the sysroot, and the normal dependency). When Miri looks up the expected argument type, it picks one of them, leading to Miri seeing a type mismatch when there is a call using the other copy. C generally considers two copies of the same type to be identical, so I implemented logic that does the same: tworepr(C)types are "identical" if the names of the types, and the names and types of all fields, are identical. I then also used that logic for the normal ABI checks, where it will also help since we had similar trouble there in the past (that we had to find other work-arounds for).