Skip to content
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 control message *decoding* and add support for ScmCredentials #923

Merged
merged 1 commit into from Aug 6, 2018

Conversation

@jonas-schievink
Copy link
Contributor

@jonas-schievink jonas-schievink commented Jul 6, 2018

While #918 fixed the encoding, the decoding done by the CmsgIterator still remained broken when multiple messages are received. However, since nix didn't support any control message that could reliably be sent twice in one sendmsg call, this couldn't be tested properly.

This PR addresses this by adding SCM_CREDENTIALS support and testing all of this by passing both an SCM_CREDENTIALS and a SCM_RIGHTS message at the same time.

I've also verified that the resulting encoding is the same as for roughly equivalent C code.

@jonas-schievink jonas-schievink force-pushed the jonas-schievink:scm-credentials branch from 06ebca0 to 108bda0 Jul 6, 2018
Copy link
Member

@asomers asomers left a comment

Looks pretty good, especially the tests. Any idea why Travis didn't build this PR?

// (although it claims the kernel header checks this), but such
// a structure is clearly invalid, either way.
// Safe if: `self.buf` is `cmsghdr`-aligned.
let cmsg: &'a cmsghdr = unsafe { &*(self.buf[..mem::size_of::<cmsghdr>()].as_ptr() as *const cmsghdr) };

This comment has been minimized.

@asomers

asomers Jul 6, 2018
Member

How do you guarantee that self.buf is correctly aligned?

This comment has been minimized.

@jonas-schievink

jonas-schievink Jul 6, 2018
Author Contributor

The caller does. In this case its done by the CmsgSpace, which ensures alignment using a properly aligned member.

This comment has been minimized.

@jonas-schievink

jonas-schievink Jul 6, 2018
Author Contributor

Well, it's not the caller but whoever creates the iterator. Here, the buffer comes from recvmsg and is a CmsgSpace which guarantees alignment.

cmsg_data.as_ptr() as *const _,
len))))
}
let cmsg_data = &self.buf[cmsg_align(mem::size_of::<cmsghdr>())..cmsg_len];

This comment has been minimized.

@asomers

asomers Jul 6, 2018
Member

Up above you requird self.buf to be aligned. Here, you seem to be handling the case where it isn't. Or am I misunderstanding?

This comment has been minimized.

@jonas-schievink

jonas-schievink Jul 6, 2018
Author Contributor

The cmsg_align just rounds up the size of cmsghdr to the right alignment. This is needed to include the right padding to reach the payload.

@@ -567,57 +569,95 @@ impl<'a> ControlMessage<'a> {
}
}

/// Returns the value to put into the `cmsg_type` field of the header.
fn type_(&self) -> libc::c_int {

This comment has been minimized.

@asomers

asomers Jul 6, 2018
Member

I don't like trailing underscores. How about naming this method cmsg_type instead?


match *self {
ControlMessage::ScmRights(fds) => {
let padlen = cmsg_align(mem::size_of_val(&cmsg)) -

This comment has been minimized.

@asomers

asomers Jul 6, 2018
Member

It looks like padlen and buf are identical for all cases. Can you move their definitions outside of the match block?

@jonas-schievink
Copy link
Contributor Author

@jonas-schievink jonas-schievink commented Jul 6, 2018

Any idea why Travis didn't build this PR?

I added [ci skip] to the last commit as it was just updating the changelog. This causes Travis to ignore the commit which saves CI time.

(the previous commit was built by Travis and passed)

@jonas-schievink
Copy link
Contributor Author

@jonas-schievink jonas-schievink commented Jul 9, 2018

Uh, now the old test fails? That's odd.

EDIT: Uh okay the tests are really flaky - I suspect there's still some issues left

@jonas-schievink
Copy link
Contributor Author

@jonas-schievink jonas-schievink commented Jul 10, 2018

I think the issues are in qemu. I haven't managed to get any socket tests failing on my Raspberry Pi 1 (armv6) or 2 (armv7). Additionally, I wrote a test program in C (https://gist.github.com/jonas-schievink/cb6e6584a055539d2113f22d91068e2d) that works fine on bare metal but also shows this behavior under qemu. The control message encoding for nix and the test program is identical, and it's the kernel (or qemu) that strips out the second message, not our decoder doing weird stuff.

I'm going to build a smaller reproducer and report the bug to qemu, then #[ignore] the tests here.

@jonas-schievink
Copy link
Contributor Author

@jonas-schievink jonas-schievink commented Jul 10, 2018

@asomers Alright, after a long journey this might be finally done (except the commit message for
386cd04 is wrong - but I'll fix that when squashing later). Care to take another look?

@@ -301,14 +301,36 @@ fn test_scm_credentials() {
/// Ensure that we can send `SCM_CREDENTIALS` and `SCM_RIGHTS` with a single
/// `sendmsg` call.
#[cfg(any(target_os = "android", target_os = "linux"))]
// qemu's handling of multiple cmsgs is bugged, ignore tests on non-x86-64
#[cfg_attr(not(target_arch = "x86_64"), ignore)]

This comment has been minimized.

@asomers

asomers Jul 11, 2018
Member

What about i386? That doesn't use qemu on FreeBSD, and I don't think it does on Linux either.

@@ -301,14 +301,36 @@ fn test_scm_credentials() {
/// Ensure that we can send `SCM_CREDENTIALS` and `SCM_RIGHTS` with a single
/// `sendmsg` call.
#[cfg(any(target_os = "android", target_os = "linux"))]
// qemu's handling of multiple cmsgs is bugged, ignore tests on non-x86-64

This comment has been minimized.

@asomers

asomers Jul 11, 2018
Member

Can you add an upstream bug link? Your C test case should make it easy to report.

@jonas-schievink jonas-schievink force-pushed the jonas-schievink:scm-credentials branch from 9f0c7da to fb960c4 Jul 11, 2018
// (although it claims the kernel header checks this), but such
// a structure is clearly invalid, either way.
// Safe if: `self.buf` is `cmsghdr`-aligned.
let cmsg: &'a cmsghdr = unsafe { &*(self.buf[..mem::size_of::<cmsghdr>()].as_ptr() as *const cmsghdr) };

This comment has been minimized.

@asomers

asomers Jul 11, 2018
Member

Wrap to 80 columns, please.

Copy link
Member

@asomers asomers left a comment

Ok, now it LGTM. All it needs is a squash. @Susurrus any comments?

@asomers
Copy link
Member

@asomers asomers commented Jul 26, 2018

@jonas-schievink please squash this; then I'll merge it.

@jonas-schievink jonas-schievink force-pushed the jonas-schievink:scm-credentials branch from 9bc15cc to 9f0af44 Jul 27, 2018
@Susurrus
Copy link
Contributor

@Susurrus Susurrus commented Aug 6, 2018

@asomers This all look good? You asked for it to be squashed, which is has been. We could split this up into two commits with the other one added the as_raw implementations for Pid and friends, but it's a minor nit, so I'm fine not worrying about it.

@asomers
asomers approved these changes Aug 6, 2018
Copy link
Member

@asomers asomers left a comment

Yep, I'm cool.

@asomers
Copy link
Member

@asomers asomers commented Aug 6, 2018

bors r+

bors bot added a commit that referenced this pull request Aug 6, 2018
Merge #923
923: Fix control message *decoding* and add support for `ScmCredentials` r=asomers a=jonas-schievink

While #918 fixed the *encoding*, the *decoding* done by the `CmsgIterator` still remained broken when multiple messages are received. However, since nix didn't support any control message that could reliably be sent twice in one `sendmsg` call, this couldn't be tested properly.

This PR addresses this by adding `SCM_CREDENTIALS` support and testing all of this by passing both an `SCM_CREDENTIALS` and a `SCM_RIGHTS` message at the same time.

I've also verified that the resulting encoding is the same as for roughly equivalent C code.

Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
@bors
Copy link
Contributor

@bors bors bot commented Aug 6, 2018

Timed out

@asomers
Copy link
Member

@asomers asomers commented Aug 6, 2018

bors retry

bors bot added a commit that referenced this pull request Aug 6, 2018
Merge #923
923: Fix control message *decoding* and add support for `ScmCredentials` r=asomers a=jonas-schievink

While #918 fixed the *encoding*, the *decoding* done by the `CmsgIterator` still remained broken when multiple messages are received. However, since nix didn't support any control message that could reliably be sent twice in one `sendmsg` call, this couldn't be tested properly.

This PR addresses this by adding `SCM_CREDENTIALS` support and testing all of this by passing both an `SCM_CREDENTIALS` and a `SCM_RIGHTS` message at the same time.

I've also verified that the resulting encoding is the same as for roughly equivalent C code.

Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
@bors bors bot merged commit 9f0af44 into nix-rust:master Aug 6, 2018
4 checks passed
4 checks passed
bors Build succeeded
Details
buildbot/nix-rust/nix amd64_fbsd11 Build done.
Details
buildbot/nix-rust/nix i386_fbsd11 Build done.
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@jonas-schievink jonas-schievink deleted the jonas-schievink:scm-credentials branch Oct 4, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

3 participants