-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Description
This issue is part of the Strict Provenance Experiment - #95228
Some system APIs (and C FFI in general) like to lie about whether things are pointers, and this makes strict-provenance very sad.
prctl for PR_SET_NAME (says a pointer is unsigned long):
rust/library/std/src/sys/unix/thread.rs
Lines 120 to 127 in 44628f7
| pub fn set_name(name: &CStr) { | |
| const PR_SET_NAME: libc::c_int = 15; | |
| // pthread wrapper only appeared in glibc 2.12, so we use syscall | |
| // directly. | |
| unsafe { | |
| libc::prctl(PR_SET_NAME, name.as_ptr() as libc::c_ulong, 0, 0, 0); | |
| } | |
| } |
clone3(?) (says a pointer is u64):
rust/library/std/src/sys/unix/process/process_unix.rs
Lines 185 to 198 in 44628f7
| if want_clone3_pidfd && HAS_CLONE3.load(Ordering::Relaxed) { | |
| let mut args = clone_args { | |
| flags: CLONE_PIDFD, | |
| pidfd: &mut pidfd as *mut pid_t as u64, | |
| child_tid: 0, | |
| parent_tid: 0, | |
| exit_signal: libc::SIGCHLD as u64, | |
| stack: 0, | |
| stack_size: 0, | |
| tls: 0, | |
| set_tid: 0, | |
| set_tid_size: 0, | |
| cgroup: 0, | |
| }; |
sigaction (defines sighandler_t (a callback) to be size_t):
| action.sa_sigaction = signal_handler as sighandler_t; |
The "level 1" fix for this is to just change our extern decls so that all of these APIs/types actually say "this is a pointer". In general it's ok for integers to pretend to be pointers "for fun", and if anything is ever int | ptr the valid union of these types is ptr.
The "level 2" fix for this is to instead come up with some general mechanism for dealing with these kinds that folks can use in the larger ecosystem, like a "this is lies" annotation or uptr. This kind of thing is especially nasty for people who are "bindgen true believers" and don't want to ever hand-edit generated bindings (so, not us).