-
Notifications
You must be signed in to change notification settings - Fork 13.6k
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).