diff --git a/netlink-proto/src/codecs.rs b/netlink-proto/src/codecs.rs index 27535f28..d5c1af48 100644 --- a/netlink-proto/src/codecs.rs +++ b/netlink-proto/src/codecs.rs @@ -1,4 +1,4 @@ -use std::{fmt::Debug, io, marker::PhantomData, slice}; +use std::{fmt::Debug, io, marker::PhantomData}; use bytes::{BufMut, BytesMut}; use netlink_packet_core::{ @@ -147,43 +147,25 @@ where fn encode(&mut self, msg: NetlinkMessage, buf: &mut BytesMut) -> Result<(), Self::Error> { let msg_len = msg.buffer_len(); - // FIXME: we should have a max length for the buffer - while buf.remaining_mut() < msg_len { - let new_len = buf.len() + 2048; - buf.resize(new_len, 0); - } - let size = msg.buffer_len(); - if buf.remaining_mut() < size { + if buf.remaining_mut() < msg_len { + // BytesMut can expand till usize::MAX... unlikely to hit this one. return Err(io::Error::new( io::ErrorKind::Other, format!( "message is {} bytes, but only {} bytes left in the buffer", - size, + msg_len, buf.remaining_mut() ), )); } - // Safety: we initialize the buffer we're passing to - // NetlinkMessage::serialize(). In theory, `serialize()` - // should be safe because it's not supposed to _read_ from - // the buffer, which is potentially - // un-initialized. However, since we delegate the actual - // implementation to users, we cannot guarantee - // anything. Therefore we have to initialize the buffer - // here. - let bytes = &mut buf.chunk_mut()[..size]; - for i in 0..bytes.len() { - bytes.write_byte(i, 0); - } - - unsafe { - let initialized_bytes = slice::from_raw_parts_mut(bytes.as_mut_ptr(), bytes.len()); - - msg.serialize(initialized_bytes); - trace!(">>> {:?}", msg); - buf.advance_mut(size); - } + // As NetlinkMessage::serialize needs an initialized buffer anyway + // no need for any `unsafe` magic. + let old_len = buf.len(); + let new_len = old_len + msg_len; + buf.resize(new_len, 0); + msg.serialize(&mut buf[old_len..][..msg_len]); + trace!(">>> {:?}", msg); Ok(()) } }