-
Notifications
You must be signed in to change notification settings - Fork 675
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
Fix struct msghdr
types on non-Linux platforms.
#648
Conversation
I'd like to take the policy that we never fix FFI stuff directly within |
Whoops, should have read your entire post. The goal is for |
a39e409
to
ed75b24
Compare
Will do. Updated PR coming soon. |
CHANGELOG.md
Outdated
@@ -66,6 +66,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). | |||
([#623](https://github.com/nix-rust/nix/pull/623)) | |||
- Multiple constants related to the termios API have now been properly defined for | |||
all supported platforms. ([#527](https://github.com/nix-rust/nix/pull/527)) | |||
- Fixed field types of `sys::socket::ffi::{msghdr, cmsghdr}` on | |||
non-Linux platforms. ([#](https://...)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can fill this in at this point. It won't change between now and when it's committed.
src/sys/socket/ffi.rs
Outdated
@@ -33,9 +48,9 @@ pub struct msghdr<'a> { | |||
pub msg_name: *const c_void, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both msghdr
and cmsghdr
here should be removed in favor of the declarations in libc
.
Apologies for the delay, I've been busy with other stuff. I'll try to get the PR updated this week with the removal of socket/ffi.rs and various fixes for this area of the code. Most of the work is already complete, it just needs tidying up. |
@kinetiknz I actually did some work in this area (see #748). Would you be willing to push this through? This is the last remaining FFI declarations in nix. |
Sure thing, apologies for letting this sit so long! |
bc98b99
to
b35564f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few minor comments, but I don't understand this code very well. I'd like to do a deeper dive on this, but before I do could you add some comments to help me out? You seem to have a good sense of this API, so it'd be really helpful getting more of that knowledge written down.
Additionally, do we have tests for this? If not, can some be written or is this a hard API for that?
src/sys/socket/mod.rs
Outdated
@@ -198,8 +203,10 @@ use self::ffi::{cmsghdr, msghdr, type_of_cmsg_data, type_of_msg_iovlen, type_of_ | |||
/// To make room for multiple messages, nest the type parameter with | |||
/// tuples, e.g. | |||
/// `let cmsg: CmsgSpace<([RawFd; 3], CmsgSpace<[RawFd; 2]>)> = CmsgSpace::new();` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should make this a doccomment so it can be compile & run tested.
src/sys/socket/mod.rs
Outdated
@@ -380,7 +388,7 @@ pub enum ControlMessage<'a> { | |||
pub struct UnknownCmsg<'a>(&'a cmsghdr, &'a [u8]); | |||
|
|||
fn cmsg_align(len: usize) -> usize { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest we add an #[inline]
here as it's a small convenience function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you also add a comment here summarizing this function? I'm having trouble following this code and having a comment for this helper function would be nice.
@kinetiknz Just pinging you again on this as it's the last nugget before we have all FFI types upstreamed. |
Sorry! I'll push my changes tomorrow. |
d9cb637
to
b464f9b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This all looks pretty correct to me, unfortunately I'm not too familiar with all of this. @asomers Could you take a look over this as well?
src/sys/socket/mod.rs
Outdated
@@ -187,8 +188,12 @@ unsafe fn copy_bytes<'a, 'b, T: ?Sized>(src: &T, dst: &'a mut &'b mut [u8]) { | |||
mem::swap(dst, &mut remainder); | |||
} | |||
|
|||
// OSX always aligns struct cmsghdr as if it were a 32-bit OS | |||
#[cfg(target_os = "macos")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this apply to ios
as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like it, thanks.
src/sys/socket/mod.rs
Outdated
@@ -187,8 +188,12 @@ unsafe fn copy_bytes<'a, 'b, T: ?Sized>(src: &T, dst: &'a mut &'b mut [u8]) { | |||
mem::swap(dst, &mut remainder); | |||
} | |||
|
|||
// OSX always aligns struct cmsghdr as if it were a 32-bit OS | |||
#[cfg(target_os = "macos")] | |||
type align_of_cmsg_data = libc::c_uint; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be u32
instead of c_uint
? Even if they are the same I'd think u32
is more clear.
src/sys/socket/mod.rs
Outdated
@@ -197,9 +202,16 @@ use self::ffi::{cmsghdr, msghdr, type_of_cmsg_data, type_of_msg_iovlen, type_of_ | |||
/// | |||
/// To make room for multiple messages, nest the type parameter with | |||
/// tuples, e.g. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the ", e.g." and add ":"
src/sys/socket/mod.rs
Outdated
cmsg_type: libc::SCM_RIGHTS, | ||
cmsg_data: [], | ||
let cmsg = { | ||
let mut cmsg: cmsghdr = mem::uninitialized(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be more clear if rewritten to use struct update syntax:
let mut cmsg = cmsghdr {
cmsg_len: self.len() as _,
cmsg_level: libc::SOL_SOCKET,
cmsg_type: libc::SCM_RIGHTS,
..unsafe { mem::uninitialized() }
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that's nicer, but it looks like the musl target prevents this due to private fields. 😞
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's only a problem for msghdr
, so I'll keep the cmsghdr
changes and revert the rest.
Also, could you rebase and squash all the commits into one since this is really a single big change? |
Will do, but I figured it'd be easier to review as a series of small commits. |
@kinetiknz I think there are just a few small things to finish to wrap this up in a nice pretty bow. You have some time soon to finish this off? |
Sure, I should have time early next week. |
@kinetiknz Will you have time to do some work on this this week? This is the last piece of |
a950024
to
a7ac04f
Compare
Sorry about the delay, rebased and squashed with the last set of comments addressed. Also adjusted the definition of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think we should basically go and merge this. I'd just ask for a simple alphetizing of a #cfg
and the struct initializing could be more clear using struct update syntax. Hopefully that's not too much to ask for this PR, cause after that let's merge!
src/sys/socket/mod.rs
Outdated
cmsg_type: libc::SCM_RIGHTS, | ||
cmsg_data: [], | ||
let cmsg = { | ||
let mut cmsg: cmsghdr = mem::uninitialized(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be more clear if rewritten to use struct update syntax:
let mut cmsg = cmsghdr {
cmsg_len: self.len() as _,
cmsg_level: libc::SOL_SOCKET,
cmsg_type: libc::SCM_RIGHTS,
..unsafe { mem::uninitialized() }
};
src/sys/socket/mod.rs
Outdated
cmsg_level: libc::SOL_SOCKET, | ||
cmsg_type: libc::SCM_TIMESTAMP, | ||
cmsg_data: [], | ||
let cmsg = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
src/sys/socket/mod.rs
Outdated
@@ -295,19 +296,30 @@ unsafe fn copy_bytes<'a, 'b, T: ?Sized>(src: &T, dst: &'a mut &'b mut [u8]) { | |||
mem::swap(dst, &mut remainder); | |||
} | |||
|
|||
// Darwin and DragonFly BSD always aligns struct cmsghdr as if it were a 32-bit OS | |||
#[cfg(any(target_os = "ios", target_os = "macos", target_os = "dragonfly"))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you alphabetize this list?
a7ac04f
to
9994365
Compare
No problem, let me know if there's anything else! |
9994365
to
2c15dc9
Compare
Repushed with musl and iOS target fixes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last tiny nitpick, then I think we're definite RTM!
src/sys/socket/mod.rs
Outdated
cmsg_level: libc::SOL_SOCKET, | ||
cmsg_type: libc::SCM_RIGHTS, | ||
cmsg_data: [], | ||
cmsg_len: self.len() as _, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this indentation is messed up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what happened there, but fixed version pushed.
2c15dc9
to
87a8562
Compare
Just realized this is more than fixing the FFI stuff, it actually fixes things on non-Linux platforms, so it's a bug fix. Can you add a CHANGELOG entry under the Fixed section for this? |
87a8562
to
19ef148
Compare
Added something, suggestions welcome if that's not clear enough. |
bors r+ |
648: Fix `struct msghdr` types on non-Linux platforms. r=Susurrus a=kinetiknz Type `struct msghdr` and `struct cmsghdr` types defined in `sys/socket/ffi.rs` match the Linux headers, but differ from the standard header (and other OSes): http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html This PR fixes a memory corruption/unsafety issue on non-Linux machines when using `recvmsg` with certain parameters. While fixing this, I wondered what the reason was for nix not using libc's definition of these structures. Closes #748.
Awesome, thanks for following through on this, @kinetiknz. And when/if you have time any additional tests and refinements are always appreciated! |
Type
struct msghdr
andstruct cmsghdr
types defined insys/socket/ffi.rs
match the Linux headers, but differ from the standard header (and other OSes): http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.htmlThis PR fixes a memory corruption/unsafety issue on non-Linux machines when using
recvmsg
with certain parameters.While fixing this, I wondered what the reason was for nix not using libc's definition of these structures.
Closes #748.