-
Notifications
You must be signed in to change notification settings - Fork 668
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
initialize msg_name with null pointer when msg_name is empty #2530
Conversation
src/sys/socket/mod.rs
Outdated
@@ -2002,7 +2002,7 @@ unsafe fn pack_mhdr_to_receive<S>( | |||
let mut mhdr = mem::MaybeUninit::<msghdr>::zeroed(); | |||
let p = mhdr.as_mut_ptr(); | |||
unsafe { | |||
(*p).msg_name = address as *mut c_void; | |||
(*p).msg_name = if S::size() == 0 { ptr::null_mut() } else { (*address).as_mut_ptr() as *mut 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.
(*address).as_mut_ptr() as *mut c_void
Any idea why it would work after reverting the change made in #2041?
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.
Considering this, gentle ping on @JarredAllen, the author of #2041, could you please take a look at this PR?
Context
@pacak is trying to solve #2506, after digging into the previous Nix versions(Thank you for this!), he figured out that the issue is possibly introduced by #2041:
If we can have you, I hope we can solve the following questions:
- The reason behind above change made in Set the length of a socket address when calling
recvmsg
on Linux #2041, and possibly why reverting it would fix Re-useMultiHeader<()>
in subsequentrecvmmsg()
calls #2506. - The things that Set the length of a socket address when calling
recvmsg
on Linux #2041 tried to fix would still work after this PR.
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.
Any idea why it would work after reverting the change made in #2041?
As far as I understand .as_mut_ptr()
gives a null pointer in case of ()
, address as *mut c_void
gives a dangling pointer through magic of rustc optimizations.
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 guess just using .as_mut_ptr()
would be enough as long as all the instances return the right pointer. Explicit checking for size makes it so it works even if there's a bogus instance.
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.
As far as I understand .as_mut_ptr() gives a null pointer in case of (), address as *mut c_void gives a dangling pointer through magic of rustc optimizations.
If so
I guess just using .as_mut_ptr() would be enough as long as all the instances return the right pointer.
then yes
not sure if things fixed by #2041 are still working after that.
I think this PR won't break the fix done by #2041 as there is a unit test guarding it.
BTW, let's document why we should use .as_mut_tr()
rather than address as *mut c_void
because it is so easy to revert the fix if one is not aware of such a subtle different behavior . 😮💨
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.
Sorry I wasn't around, but thanks for fixing my mistake! I concur with the assessment that this shouldn't break my fix.
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.
No need to be sorry. 😆
The msg_name field points to a caller-allocated buffer that is used to return the source address if the socket is unconnected. The caller should set msg_namelen to the size of this buffer before this call; upon return from a successful call, msg_namelen will contain the length of the returned address. If the application does not need to know the source address, msg_name can be specified as NULL. In case we use () msgname_len gets initialized with 0, but a dangling pointer to the array with msg_name. This works for the first iteration somehow, but after that kernel sets msgname_len to a non-zero and second invocation with the same MultiHeader fails Fixes nix-rust#2506
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.
Thanks! Appreciate the patience when you struggle with the format.
The msg_name field points to a caller-allocated buffer that is used to return the source address if the socket is unconnected. The caller should set msg_namelen to the size of this buffer before this call; upon return from a successful call, msg_namelen will contain the length of the returned address. If the application does not need to know the source address, msg_name can be specified as NULL.
In case we use () msgname_len gets initialized with 0, but pointer to the array with msg_name. This works for the first iteration somehow, but after that kernel sets msgname_len to a non-zero and second invocation with the same MultiHeader fails
What does this PR do
Fixes #2506
Checklist:
CONTRIBUTING.md