Skip to content

Commit 7baaccd

Browse files
committed
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
1 parent f38b721 commit 7baaccd

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

src/sys/aio.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,8 +1051,14 @@ pub fn aio_suspend(
10511051
list: &[&dyn AsRef<libc::aiocb>],
10521052
timeout: Option<TimeSpec>,
10531053
) -> Result<()> {
1054-
let p = list as *const [&dyn AsRef<libc::aiocb>]
1055-
as *const [*const libc::aiocb] as *const *const libc::aiocb;
1054+
// Note that this allocation could be eliminated by making the argument
1055+
// generic, and accepting arguments like &[AioWrite]. But that would
1056+
// prevent using aio_suspend to wait on a heterogeneous list of mixed
1057+
// operations.
1058+
let v = list.iter()
1059+
.map(|x| x.as_ref() as *const libc::aiocb)
1060+
.collect::<Vec<*const libc::aiocb>>();
1061+
let p = v.as_ptr();
10561062
let timep = match timeout {
10571063
None => ptr::null::<libc::timespec>(),
10581064
Some(x) => x.as_ref() as *const libc::timespec,
@@ -1172,6 +1178,7 @@ pub fn aio_suspend(
11721178
/// // notification, we know that all operations are complete.
11731179
/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len());
11741180
/// ```
1181+
#[deprecated(since = "0.27.0", note = "https://github.com/nix-rust/nix/issues/2017")]
11751182
pub fn lio_listio(
11761183
mode: LioMode,
11771184
list: &mut [Pin<&mut dyn AsMut<libc::aiocb>>],

0 commit comments

Comments
 (0)