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(s2n-quic-platform): use custom storage type for messages #1807

Merged
merged 1 commit into from
Jun 15, 2023

Conversation

camshaft
Copy link
Contributor

@camshaft camshaft commented Jun 12, 2023

Description of changes:

In #1790, @Mark-Simulacrum had some concerns about the code from #1787. This PR aims to address those separately.

Call-outs:

There were a few violations of stacked borrows in the cmsg module. Unfortunately, they aren't completely solvable, as some of them come from the libc crate. I've modified the code to use our own cmsg implementation, which actually simplifies things a bit.

Testing:

I've added MIRI tests for the s2n-quic-platform crate to ensure we don't violate the stacked borrows memory model. I've also added a few Kani tests to increase some confidence in the new cmsg code.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Copy link
Collaborator

@Mark-Simulacrum Mark-Simulacrum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re:UnsafeCells -- you probably know better than I if there's some kind of locking (semantic or through actual atomics etc) going on with &Header being converted to &mut Header. My current impression is that we always work with raw pointers if there's shared ownership (e.g., for the range of memory that is potentially shared with the kernel) and only convert to &Header and/or &mut Header if we have ownership of that region based on the start/end pointers and such.

Happy to sync up if this doesn't help explain my mental model enough.

quic/s2n-quic-platform/src/message.rs Outdated Show resolved Hide resolved
quic/s2n-quic-platform/src/message.rs Outdated Show resolved Hide resolved
quic/s2n-quic-platform/src/message/msg.rs Outdated Show resolved Hide resolved
quic/s2n-quic-platform/src/message/msg.rs Outdated Show resolved Hide resolved
quic/s2n-quic-platform/src/message/msg.rs Outdated Show resolved Hide resolved
@camshaft camshaft force-pushed the camshaft/ring-fixes branch 2 times, most recently from 6251aa0 to 367cd0c Compare June 13, 2023 18:18
@camshaft camshaft marked this pull request as ready for review June 13, 2023 18:43
@camshaft camshaft requested review from toidiu and removed request for Mark-Simulacrum June 13, 2023 18:43
@camshaft
Copy link
Contributor Author

Looks like the cmsg changes broke ECN... still investigating why

@camshaft
Copy link
Contributor Author

Alright; managed to get everything fixed!

@camshaft camshaft requested review from WesleyRosenblum and removed request for toidiu June 14, 2023 19:31
@@ -16,17 16,30 @@ fn main() -> Result<(), Error> {
}
}

let is_miri = std::env::var("CARGO_CFG_MIRI").is_ok();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't use cfg!(miri) for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cfg isn't passed to build scripts themselves, since they run on a different "platform" than the code that they're compiling.

unsafe { libc::CMSG_SPACE(size_of::<T>() as _) as _ }
}

const fn const_max(a: usize, b: usize) -> usize {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to suggest linking to rust-lang/rust#92391 in a TODO, but seems like that is going in a different direction anyway


// This is currently needed due to how we detect if CMSG data has been written or not.
//
// TODO remove this once we split the `reset` traits into TX and RX types
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you tracking this somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's in my later PRs so it's already done; just is waiting on deleting the socket v1

// Applications should not cast it to a pointer type matching the
// payload, but should instead use memcpy(3) to copy data to or
// from a suitably declared object.
let data_ptr = cmsg_ptr.add(1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure I'm following why its adding 1 here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's what the CMSG_DATA function does, except ours is actually sound since we're not going from a *const to a *mut. I've including the call to CMSG_DATA in a debug_assertion to make sure they return the same thing.

#[test]
#[cfg_attr(any(target_os = "linux", target_os = "android"), ignore)] // the linux implementation currently has an integer overflow on garbage data
#[cfg_attr(kani, kani::proof, kani::solver(cadical), kani::unwind(17))]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is cadical the go to now for Kani, or did you try kissat and it was slower?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cadical ended up being faster in this case. I think it just depends on the harness. The advantage cadical has is it's built in process to cbmc, as opposed to kissat that's an external binary. This forces cbmc to write a cnf to disk and then pass to kissat. Cadical APIs, instead, can just be called directly.

Comment on lines 372 to 373
#[cfg(any(not(kani), kani_slow))] // this test takes too much memory for our CI
// environment
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow really?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it was something like 16Gb, IIRC

@camshaft camshaft merged commit 8aa7a43 into main Jun 15, 2023
124 checks passed
@camshaft camshaft deleted the camshaft/ring-fixes branch June 15, 2023 00:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants