aya: netlink: fix handling of multipart messages

pull/32/head
Alessandro Decina 3 years ago
parent 9185f32f6f
commit abb199e6f4

@ -258,7 +258,7 @@ impl NetlinkSocket {
let mut buf = [0u8; 4096]; let mut buf = [0u8; 4096];
let mut messages = Vec::new(); let mut messages = Vec::new();
let mut multipart = true; let mut multipart = true;
while multipart { 'out: while multipart {
multipart = false; multipart = false;
// Safety: libc wrapper // Safety: libc wrapper
let len = unsafe { recv(self.sock, buf.as_mut_ptr() as *mut _, buf.len(), 0) }; let len = unsafe { recv(self.sock, buf.as_mut_ptr() as *mut _, buf.len(), 0) };
@ -284,7 +284,7 @@ impl NetlinkSocket {
} }
return Err(io::Error::from_raw_os_error(-err.error)); return Err(io::Error::from_raw_os_error(-err.error));
} }
NLMSG_DONE => break, NLMSG_DONE => break 'out,
_ => messages.push(message), _ => messages.push(message),
} }
} }
@ -303,11 +303,19 @@ struct NetlinkMessage {
impl NetlinkMessage { impl NetlinkMessage {
fn read(buf: &[u8]) -> Result<NetlinkMessage, io::Error> { fn read(buf: &[u8]) -> Result<NetlinkMessage, io::Error> {
if mem::size_of::<nlmsghdr>() > buf.len() { if mem::size_of::<nlmsghdr>() > buf.len() {
return Err(io::Error::new(io::ErrorKind::Other, "need more data")); return Err(io::Error::new(
io::ErrorKind::Other,
"buffer smaller than nlmsghdr",
));
} }
// Safety: nlmsghdr is POD so read is safe // Safety: nlmsghdr is POD so read is safe
let header = unsafe { ptr::read_unaligned(buf.as_ptr() as *const nlmsghdr) }; let header = unsafe { ptr::read_unaligned(buf.as_ptr() as *const nlmsghdr) };
let msg_len = header.nlmsg_len as usize;
if msg_len < mem::size_of::<nlmsghdr>() || msg_len > buf.len() {
return Err(io::Error::new(io::ErrorKind::Other, "invalid nlmsg_len"));
}
let data_offset = align_to(mem::size_of::<nlmsghdr>(), NLMSG_ALIGNTO as usize); let data_offset = align_to(mem::size_of::<nlmsghdr>(), NLMSG_ALIGNTO as usize);
if data_offset >= buf.len() { if data_offset >= buf.len() {
return Err(io::Error::new(io::ErrorKind::Other, "need more data")); return Err(io::Error::new(io::ErrorKind::Other, "need more data"));
@ -315,7 +323,10 @@ impl NetlinkMessage {
let (data, error) = if header.nlmsg_type == NLMSG_ERROR as u16 { let (data, error) = if header.nlmsg_type == NLMSG_ERROR as u16 {
if data_offset + mem::size_of::<nlmsgerr>() > buf.len() { if data_offset + mem::size_of::<nlmsgerr>() > buf.len() {
return Err(io::Error::new(io::ErrorKind::Other, "need more data")); return Err(io::Error::new(
io::ErrorKind::Other,
"NLMSG_ERROR but not enough space for nlmsgerr",
));
} }
( (
Vec::new(), Vec::new(),
@ -325,7 +336,7 @@ impl NetlinkMessage {
}), }),
) )
} else { } else {
(buf[data_offset..].to_vec(), None) (buf[data_offset..msg_len].to_vec(), None)
}; };
Ok(NetlinkMessage { Ok(NetlinkMessage {

Loading…
Cancel
Save