From 0ff46212a58381dd0954735fa53d4349c2d27f8d Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Tue, 7 Nov 2023 18:37:03 -0800 Subject: [PATCH] Pass pointers, not slices, to libc::ioctl (#2181) Slices are not FFI-safe. &[u8] and &mut [u8] are *wide pointers*, which means that at the moment, we're getting lucky because they're passed via the "ScalarPair" ABI, and this means that passing a `&[u8]` results in passing two arguments, `*const u8` and `usize` for pointer and length. This passes an extra argument to ioctl, which happens to work because the extra vararg is skipped. We're getting lucky right now, and we should explicitly pass the pointer we meant to pass instead. This is normally checked on `extern "C"` functions, but `ioctl` in particular uses varargs which prevents the compiler check from reporting. --- src/sys/ioctl/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sys/ioctl/mod.rs b/src/sys/ioctl/mod.rs index 0b3fe3e769..af846f21bb 100644 --- a/src/sys/ioctl/mod.rs +++ b/src/sys/ioctl/mod.rs @@ -181,7 +181,7 @@ //! pub unsafe fn spi_message(fd: c_int, data: &mut [spi_ioc_transfer]) -> Result { //! let res = libc::ioctl(fd, //! request_code_write!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, data.len() * mem::size_of::()), -//! data); +//! data.as_ptr()); //! Errno::result(res) //! } //! # fn main() {} @@ -712,7 +712,7 @@ macro_rules! ioctl_read_buf { pub unsafe fn $name(fd: $crate::libc::c_int, data: &mut [$ty]) -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data)) + convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data.as_mut_ptr())) } ) } @@ -751,7 +751,7 @@ macro_rules! ioctl_write_buf { pub unsafe fn $name(fd: $crate::libc::c_int, data: &[$ty]) -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data)) + convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data.as_ptr())) } ) } @@ -780,7 +780,7 @@ macro_rules! ioctl_readwrite_buf { pub unsafe fn $name(fd: $crate::libc::c_int, data: &mut [$ty]) -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data)) + convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data.as_mut_ptr())) } ) }