Skip to content

Commit 5cce099

Browse files
committed
Fix panic on dropping RecvAncillaryBuffer after failed recvmsg
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.
1 parent 730b0d2 commit 5cce099

File tree

2 files changed

+13
-9
lines changed

2 files changed

+13
-9
lines changed

src/backend/libc/net/msghdr.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use super::super::c;
77
use super::super::conv::{msg_control_len, msg_iov_len};
88
use super::super::net::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6};
99

10-
use crate::io::{IoSlice, IoSliceMut};
10+
use crate::io::{self, IoSlice, IoSliceMut};
1111
use crate::net::{RecvAncillaryBuffer, SendAncillaryBuffer, SocketAddrV4, SocketAddrV6};
1212
use crate::utils::as_ptr;
1313

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

3838
// Reset the control length.
39-
unsafe {
40-
control.set_control_len(msghdr.msg_controllen.try_into().unwrap_or(usize::MAX));
39+
if res.is_ok() {
40+
unsafe {
41+
control.set_control_len(msghdr.msg_controllen.try_into().unwrap_or(usize::MAX));
42+
}
4143
}
4244

4345
res

src/backend/linux_raw/net/msghdr.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use super::super::c;
99
use super::super::net::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6};
1010

11-
use crate::io::{IoSlice, IoSliceMut};
11+
use crate::io::{self, IoSlice, IoSliceMut};
1212
use crate::net::{RecvAncillaryBuffer, SendAncillaryBuffer, SocketAddrV4, SocketAddrV6};
1313
use crate::utils::as_ptr;
1414

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

5151
// Reset the control length.
52-
unsafe {
53-
control.set_control_len(msghdr.msg_controllen.try_into().unwrap_or(usize::MAX));
52+
if res.is_ok() {
53+
unsafe {
54+
control.set_control_len(msghdr.msg_controllen.try_into().unwrap_or(usize::MAX));
55+
}
5456
}
5557

5658
res

0 commit comments

Comments
 (0)