-
Notifications
You must be signed in to change notification settings - Fork 654
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Misaligned reference constructed by ControlMessage::ScmTimestamp #999
Comments
Do you have an example program demonstrating the bug? |
No, I don't have access to a macOS machine to test on, and at any rate you can mostly get away with ignoring alignment on modern x86. The chain of logic is straightforward, though; the alignment of |
This is hard to fix in a backwards-compatible way. I see three options:
What do you think @Susurrus ? I'm inclined to go with option 3 because it's simplest for users, even though it's complicated for us. |
I've been imagining something like: pub enum ControlMessage<'a> {
ScmRights(ScmRights<'a>),
Timestamp(Timestamp<'a>),
// ...
}
pub struct ScmRights<'a>(&'a [u8]);
impl ScmRights {
pub fn iter(&self) -> impl Iterator<Item=c_int> {
self.0.chunks(mem::size_of::<c_int>())
.map(|x| NativeEndian::read_uint(x, mem::size_of::<c_int>()) as _)
}
}
pub struct Timestamp<'a>(&'a [u8]);
impl Timestamp {
pub fn get(&self) -> timeval { unsafe { ptr::read_unaligned(self.0.as_ptr() as _) } }
} This avoids any extra allocation or copying, in effect just forcing people to use unaligned reads where needed. It's a breaking change, but any change other than silently allocating a suitably-aligned buffer and copying into it behind the scenes would be breaking. |
On some platforms the alignment of cmsg_data could be less than the alignment of the messages that it contains. That led to unaligned reads on those platforms. This change fixes the issue by always copying the message contents into aligned objects. The change is not 100% backwards compatible when using recvmsg. Users may have to replace code like this: ```rust if let ControlMessage::ScmRights(&fds) = cmsg { ``` with this: ```rust if let ControlMessageOwned::ScmRights(fds) = cmsg { ``` Fixes nix-rust#999
On some platforms the alignment of cmsg_data could be less than the alignment of the messages that it contains. That led to unaligned reads on those platforms. This change fixes the issue by always copying the message contents into aligned objects. The change is not 100% backwards compatible when using recvmsg. Users may have to replace code like this: ```rust if let ControlMessage::ScmRights(&fds) = cmsg { ``` with this: ```rust if let ControlMessageOwned::ScmRights(fds) = cmsg { ``` Fixes nix-rust#999
On some platforms the alignment of cmsg_data could be less than the alignment of the messages that it contains. That led to unaligned reads on those platforms. This change fixes the issue by always copying the message contents into aligned objects. The change is not 100% backwards compatible when using recvmsg. Users may have to replace code like this: ```rust if let ControlMessage::ScmRights(&fds) = cmsg { ``` with this: ```rust if let ControlMessageOwned::ScmRights(fds) = cmsg { ``` Fixes nix-rust#999
On some platforms the alignment of cmsg_data could be less than the alignment of the messages that it contains. That led to unaligned reads on those platforms. This change fixes the issue by always copying the message contents into aligned objects. The change is not 100% backwards compatible when using recvmsg. Users may have to replace code like this: ```rust if let ControlMessage::ScmRights(&fds) = cmsg { ``` with this: ```rust if let ControlMessageOwned::ScmRights(fds) = cmsg { ``` Fixes nix-rust#999
On some platforms the alignment of cmsg_data could be less than the alignment of the messages that it contains. That led to unaligned reads on those platforms. This change fixes the issue by always copying the message contents into aligned objects. The change is not 100% backwards compatible when using recvmsg. Users may have to replace code like this: ```rust if let ControlMessage::ScmRights(&fds) = cmsg { ``` with this: ```rust if let ControlMessageOwned::ScmRights(fds) = cmsg { ``` Fixes nix-rust#999
On some platforms the alignment of cmsg_data could be less than the alignment of the messages that it contains. That led to unaligned reads on those platforms. This change fixes the issue by always copying the message contents into aligned objects. The change is not 100% backwards compatible when using recvmsg. Users may have to replace code like this: ```rust if let ControlMessage::ScmRights(&fds) = cmsg { ``` with this: ```rust if let ControlMessageOwned::ScmRights(fds) = cmsg { ``` Fixes nix-rust#999
On macOS (and maybe other systems?) cmsg data is 4-byte aligned. In 64-bit macOS environments,
libc::timeval
contains 8-byte values, and is presumably 8-byte aligned.ControlMessage
directly converts the pointer to the cmsg data into a typed reference, which is therefore apparently unaligned and incurs UB. It seems like the only safe thing to do here would be to useptr::read_unaligned
.The text was updated successfully, but these errors were encountered: