Skip to content

Commit

Permalink
Fix panic on dropping RecvAncillaryBuffer after failed recvmsg
Browse files Browse the repository at this point in the history
Calling drain on `RecvAncillaryBuffer`, including in its `Drop`
implementation was failing, with an "attempted to subtract with
overflow" error in `cvt_msg`.

If `recvmsg` returns `-1`, `msg_controllen` will not be updated by the
call. So it had a non-zero value as passed into the function, despite
there not being any control messages to parse.
  • Loading branch information
ids1024 committed May 22, 2023
1 parent 730b0d2 commit 5cce099
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 9 deletions.
12 changes: 7 additions & 5 deletions src/backend/libc/net/msghdr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use super::super::c;
use super::super::conv::{msg_control_len, msg_iov_len};
use super::super::net::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6};

use crate::io::{IoSlice, IoSliceMut};
use crate::io::{self, IoSlice, IoSliceMut};
use crate::net::{RecvAncillaryBuffer, SendAncillaryBuffer, SocketAddrV4, SocketAddrV6};
use crate::utils::as_ptr;

Expand All @@ -19,8 +19,8 @@ pub(crate) fn with_recv_msghdr<R>(
name: &mut MaybeUninit<c::sockaddr_storage>,
iov: &mut [IoSliceMut<'_>],
control: &mut RecvAncillaryBuffer<'_>,
f: impl FnOnce(&mut c::msghdr) -> R,
) -> R {
f: impl FnOnce(&mut c::msghdr) -> io::Result<R>,
) -> io::Result<R> {
let namelen = size_of::<c::sockaddr_storage>() as c::socklen_t;
let mut msghdr = {
let mut h: c::msghdr = unsafe { zeroed() };
Expand All @@ -36,8 +36,10 @@ pub(crate) fn with_recv_msghdr<R>(
let res = f(&mut msghdr);

// Reset the control length.
unsafe {
control.set_control_len(msghdr.msg_controllen.try_into().unwrap_or(usize::MAX));
if res.is_ok() {
unsafe {
control.set_control_len(msghdr.msg_controllen.try_into().unwrap_or(usize::MAX));
}
}

res
Expand Down
10 changes: 6 additions & 4 deletions src/backend/linux_raw/net/msghdr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use super::super::c;
use super::super::net::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6};

use crate::io::{IoSlice, IoSliceMut};
use crate::io::{self, IoSlice, IoSliceMut};
use crate::net::{RecvAncillaryBuffer, SendAncillaryBuffer, SocketAddrV4, SocketAddrV6};
use crate::utils::as_ptr;

Expand All @@ -31,7 +31,7 @@ pub(crate) fn with_recv_msghdr<R>(
name: &mut MaybeUninit<c::sockaddr_storage>,
iov: &mut [IoSliceMut<'_>],
control: &mut RecvAncillaryBuffer<'_>,
f: impl FnOnce(&mut c::msghdr) -> R,
f: impl FnOnce(&mut c::msghdr) -> io::Result<R>,
) -> R {
let namelen = size_of::<c::sockaddr_storage>() as c::c_int;
let mut msghdr = c::msghdr {
Expand All @@ -49,8 +49,10 @@ pub(crate) fn with_recv_msghdr<R>(
let res = f(&mut msghdr);

// Reset the control length.
unsafe {
control.set_control_len(msghdr.msg_controllen.try_into().unwrap_or(usize::MAX));
if res.is_ok() {
unsafe {
control.set_control_len(msghdr.msg_controllen.try_into().unwrap_or(usize::MAX));
}
}

res
Expand Down

0 comments on commit 5cce099

Please sign in to comment.