Repository navigation
Add sendto and recvfrom to UnixSocketFileDescription - #5501
Conversation
|
Reminder, once the PR becomes ready for a review, use |
98f0a31 to
fc37ead
Compare
|
@rustbot ready |
d6542ac to
17a82b7
Compare
|
My new tests pass in Miri but fail natively. Seems like the behavior is still not quite right? |
|
@rustbot author |
17a82b7 to
fd421aa
Compare
Head branch was pushed to by a user without write access
fd421aa to
0221934
Compare
|
I integrated your commit into mine such that the The @rustbot ready |
|
Now behavior is wrong if the address pointer is 0. ;) In that case it apparently does not update the length. Also strangely on my system I cannot reproduce the "length gets reset to 0" any more? I get this instead |
|
Ah, it's not happy if the value addr-len-ptr points to is too big. So it definitely always reads that pointer? I assume that means it must not be null or dangling. EDIT: No it's not the size. It's fine with 1338 or 1500. But not with 1337. ?!?? |
|
Oh wait the "bad address" happens later in a different test. 🤦 So anyway for recvfrom I think we should have a test where the addr pointers is null and the len pointer is dangling but non-null, and a test where the addr pointer is dangling-non-null and the len pointer valid, and it needs to be overwritten by 0. For sendto, I think the logic is -- if the len or addr ptr are null, we are done, but otherwise we actually load the address? Or maybe we just always return "bad address"? Not sure here. |
0221934 to
6b75301
Compare
Linux seems to actually load the address as soon as neither argument is zero/null. However, this directly contradicts their man page (and also the POSIX man page) of libc_utils::write_all_generic(
TEST_BYTES.as_ptr().cast(),
TEST_BYTES.len(),
libc_utils::NoRetry,
|buf, count| {
libc::sendto(
peerfd,
buf,
count,
0,
ptr::without_provenance_mut::<libc::sockaddr>(16),
16,
)
},
) |
c1dd517 to
c565262
Compare
|
Turns out there is more BSD-specific behavior:
We now skip those tests on native BSDs. |
Maybe that should actually be raise UB then. Given the POSIX docs and behavior of BSDs, I am inclined to say that if the address pointer is non-null, we always overwrite the length pointer with 0. I think POSIX allows this, and Linux being extra liberal is not something we have to model given that other Unixes apparently are closer to POSIX here. |
|
@rustbot author |
c565262 to
f272d5e
Compare
This is exactly what we currently do. The problem with those BSD hosts is that they read the address length pointer even when the address pointer is null, and in our test case this address length pointer is a pointer without provenance. @rustbot ready |
|
Oh I see. The length ptr is documented by POSIX as
So POSIX seems to permit what the BSDs are doing. |
|
Yes, the question is whether we want to implement this edge case for BSD targets, or whether we accept an API difference there. |
506ca7f to
b1cc037
Compare
|
I added a commit that implements what seems like a reasonable check, that covers the recvfrom behavior we saw on BSD: if a length pointer is present, then the value it stores initially actually must be the size of the buffer that the address pointer points to, even if we are not going to write anything. |
b1cc037 to
06afe54
Compare
06afe54 to
1c5b05d
Compare
| } | ||
|
|
||
| if cfg!(miri) || !cfg!(any(target_os = "freebsd", target_vendor = "apple")) { | ||
| // On macOS and FreeBSD hosts we get EINVAL when the address pointer is a nullptr. |
There was a problem hiding this comment.
FWIW I cannot reproduce this, I think some results got mixed up. See #5576.
This pull request adds support for the
sendtoandrecvfromsocket operations to theUnixSocketFileDescriptiontrait.Additionally, it also implements them for the TCP socket shim. Since TCP sockets are "connection-mode", they are mostly the same as
recvandsend.