From 009d07179eb73a9152c8111d0d40125d16819c92 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 18 Feb 2025 06:20:09 -0800 Subject: [PATCH 1/5] Use `io_uring_ptr` for pointers in `io_uring_getevents_arg`. io_uring represents pointers as `u64`. Rustix uses an `io_uring_ptr` struct which is layout-compatible with `u64` but preserves pointer provenance. --- CHANGES.md | 9 +++++++++ src/io_uring/mod.rs | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index c8a1de780..5fbb470b4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -230,5 +230,14 @@ advice applies to the end of the file. To convert an arbitrary `u64` value to [`rustix::fs::fadvise`]: https://docs.rs/rustix/1.0.0/rustix/fs/fn.fadvise.html +The [`sigmask`] and [`ts`] fields of [`rustix::io_uring::getevents_arg`] +changed from `u64` to [`rustix::io_uring::io_uring_ptr`], to better preserve +pointer provenance. + +[`sigmask`]: https://docs.rs/rustix/1.0.0/rustix/io_uring/struct.io_uring_getevents_arg.html#structfield.sigmask +[`ts`]: https://docs.rs/rustix/1.0.0/rustix/io_uring/struct.io_uring_getevents_arg.html#structfield.ts +[`rustix::io_uring::getevents_arg`]: https://docs.rs/rustix/1.0.0/rustix/io_uring/struct.io_uring_getevents_arg.html +[`rustix::io_uring::io_uring_ptr`]: https://docs.rs/rustix/1.0.0-prerelease.0/rustix/io_uring/struct.io_uring_ptr.html + All explicitly deprecated functions and types have been removed. Their deprecation messages will have identified alternatives. diff --git a/src/io_uring/mod.rs b/src/io_uring/mod.rs index 20c3ba679..6b6a18a56 100644 --- a/src/io_uring/mod.rs +++ b/src/io_uring/mod.rs @@ -1395,10 +1395,10 @@ pub struct io_uring_rsrc_update2 { #[repr(C)] #[derive(Debug, Copy, Clone, Default)] pub struct io_uring_getevents_arg { - pub sigmask: u64, + pub sigmask: io_uring_ptr, pub sigmask_sz: u32, pub min_wait_usec: u32, - pub ts: u64, + pub ts: io_uring_ptr, } #[allow(missing_docs)] From 31f1603bf6f6346c113354f4d9b59478b833a43b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 20 Feb 2025 08:12:58 -0800 Subject: [PATCH 2/5] Align io_uring_ptr to 8. --- src/io_uring/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/io_uring/mod.rs b/src/io_uring/mod.rs index 6b6a18a56..df2d3c52e 100644 --- a/src/io_uring/mod.rs +++ b/src/io_uring/mod.rs @@ -958,7 +958,7 @@ pub const IORING_NOTIF_USAGE_ZC_COPIED: i32 = sys::IORING_NOTIF_USAGE_ZC_COPIED /// `io_uring`'s native API represents pointers as `u64` values. In order to /// preserve strict-provenance, use a `*mut c_void`. On platforms where /// pointers are narrower than 64 bits, this requires additional padding. -#[repr(C)] +#[repr(C, align(8))] #[derive(Copy, Clone)] #[non_exhaustive] pub struct io_uring_ptr { @@ -1560,6 +1560,7 @@ mod tests { use sys as c; assert_eq_size!(io_uring_ptr, u64); + assert_eq_align!(io_uring_ptr, u64); check_renamed_type!(off_or_addr2_union, io_uring_sqe__bindgen_ty_1); check_renamed_type!(addr_or_splice_off_in_union, io_uring_sqe__bindgen_ty_2); From f62447137955b763078e510209dc89b9b4589c79 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 20 Feb 2025 08:18:42 -0800 Subject: [PATCH 3/5] Only on arm. --- src/io_uring/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/io_uring/mod.rs b/src/io_uring/mod.rs index df2d3c52e..901cccbed 100644 --- a/src/io_uring/mod.rs +++ b/src/io_uring/mod.rs @@ -958,7 +958,8 @@ pub const IORING_NOTIF_USAGE_ZC_COPIED: i32 = sys::IORING_NOTIF_USAGE_ZC_COPIED /// `io_uring`'s native API represents pointers as `u64` values. In order to /// preserve strict-provenance, use a `*mut c_void`. On platforms where /// pointers are narrower than 64 bits, this requires additional padding. -#[repr(C, align(8))] +#[repr(C)] +#[cfg_attr(target_arch = "arm", repr(align(8)))] #[derive(Copy, Clone)] #[non_exhaustive] pub struct io_uring_ptr { From 8c52c618f7a68de0127c4402b4fb087c9296bca6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 20 Feb 2025 16:30:20 -0800 Subject: [PATCH 4/5] Add a testcase for io_uring_ptr. --- src/io_uring/mod.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/io_uring/mod.rs b/src/io_uring/mod.rs index 901cccbed..0d0400389 100644 --- a/src/io_uring/mod.rs +++ b/src/io_uring/mod.rs @@ -1560,9 +1560,24 @@ mod tests { fn io_uring_layouts() { use sys as c; + // `io_uring_ptr` is a replacement for `u64`. assert_eq_size!(io_uring_ptr, u64); assert_eq_align!(io_uring_ptr, u64); + // Test that pointers are stored in io_uring_ptr` in the way that + // io_uring stores them in a `u64`. + unsafe { + const MAGIC: u64 = !0x0123456789abcdef; + let ptr = io_uring_ptr::from(core::ptr::without_provenance_mut(MAGIC as usize)); + assert_eq!(ptr.ptr, core::ptr::without_provenance_mut(MAGIC as usize)); + #[cfg(target_pointer_width = "16")] + assert_eq!(ptr.__pad16, 0); + #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))] + assert_eq!(ptr.__pad32, 0); + let int = core::mem::transmute::(ptr); + assert_eq!(int, MAGIC as usize as u64); + } + check_renamed_type!(off_or_addr2_union, io_uring_sqe__bindgen_ty_1); check_renamed_type!(addr_or_splice_off_in_union, io_uring_sqe__bindgen_ty_2); check_renamed_type!(addr3_or_cmd_union, io_uring_sqe__bindgen_ty_6); From 3fdb49e5b5b8c873f11a1ee1f3c689adc6037ca0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 20 Feb 2025 17:03:24 -0800 Subject: [PATCH 5/5] Fix compilation on Rust 1.63. --- src/io_uring/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/io_uring/mod.rs b/src/io_uring/mod.rs index 0d0400389..e0fda2c32 100644 --- a/src/io_uring/mod.rs +++ b/src/io_uring/mod.rs @@ -1568,8 +1568,8 @@ mod tests { // io_uring stores them in a `u64`. unsafe { const MAGIC: u64 = !0x0123456789abcdef; - let ptr = io_uring_ptr::from(core::ptr::without_provenance_mut(MAGIC as usize)); - assert_eq!(ptr.ptr, core::ptr::without_provenance_mut(MAGIC as usize)); + let ptr = io_uring_ptr::from(MAGIC as usize as *mut c_void); + assert_eq!(ptr.ptr, MAGIC as usize as *mut c_void); #[cfg(target_pointer_width = "16")] assert_eq!(ptr.__pad16, 0); #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]