From 7baaccdf347a03e60477e0e013f3acf0568e126a Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Sun, 2 Apr 2023 10:01:36 -0600 Subject: [PATCH] Fix aio_suspend in non-trivial cases aio_suspend would probably fail with EFAULT if the first operation in the list wasn't complete, due to an invalid pointer cast. Also, deprecate lio_listio, which has the same problem, and others besides. Fixes #1980 --- src/sys/aio.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/sys/aio.rs b/src/sys/aio.rs index ee78d9c2f0..bd4c122916 100644 --- a/src/sys/aio.rs +++ b/src/sys/aio.rs @@ -1051,8 +1051,14 @@ pub fn aio_suspend( list: &[&dyn AsRef], timeout: Option, ) -> Result<()> { - let p = list as *const [&dyn AsRef] - as *const [*const libc::aiocb] as *const *const libc::aiocb; + // Note that this allocation could be eliminated by making the argument + // generic, and accepting arguments like &[AioWrite]. But that would + // prevent using aio_suspend to wait on a heterogeneous list of mixed + // operations. + let v = list.iter() + .map(|x| x.as_ref() as *const libc::aiocb) + .collect::>(); + let p = v.as_ptr(); let timep = match timeout { None => ptr::null::(), Some(x) => x.as_ref() as *const libc::timespec, @@ -1172,6 +1178,7 @@ pub fn aio_suspend( /// // notification, we know that all operations are complete. /// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len()); /// ``` +#[deprecated(since = "0.27.0", note = "https://github.com/nix-rust/nix/issues/2017")] pub fn lio_listio( mode: LioMode, list: &mut [Pin<&mut dyn AsMut>],