-
Notifications
You must be signed in to change notification settings - Fork 2
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
Safety properties? #3
Comments
The equivalent trait in |
We did not consider the problem of peers being malignant when working on our shared memory use-cases as all the code we cared about was controlled by us in its entirety. The traits in this crate presume that mutability properties of certain data are maintained and so That being said, my memory of this crate is fairly dry by this point, @Ekleog or @lovesegfault might have something else to add. |
IIRC we used to make it so that readers had RO access, cc. @Ekleog. Also, @nagisa, we should really open source shmem, I'll do it while sick. EDIT: Leo did it! https://github.com/standard-ai/shmem |
That is no longer true, and doesn’t really solve any of the issues raised by the OP in the first place AFAICT, as writer would still be able to invalidate compiler’s notion of |
Yeah, absolutely. I think if your writers are evil than you're always going to be fucked, no? |
Well shared-data tries to be safe even in the presence of malicious writes; malicious truncation of the shared memory file is something you can't do much about. rust-lang/unsafe-code-guidelines#215 has a lot of discussion about what Rust can assume in terms of its run-time environement, and rust-lang/unsafe-code-guidelines#152 is a discussion of volatile read of untrusted memory (the issue there being that LLVM goes and treats that as potentially being UB, and Rust inherits that from LLVM, sigh). There are some types that are safe to take references to, even in the presence of malicious writers. The poster child is |
@asajeffrey In this crate, we are considering all the processes having access to the shared memory region as being bound by the rust type system, and as respecting the invariants in the unsafe functions that can be called -- in this way, they are assumed to be adverse actors but bound by the type system and invariants of the functions. The aim is to allow for fast cross-process communication, for which volatile read/writes would be impossible. Also, volatile read/writes are not enough to prevent all UB, and you would actually need de/serializing to protect the stuff properly -- for instance, as far as I understand your code, That being said, I think I would see a point in having a trait for “this type is safe to put in shared memory in a purely adversarial context (ie. the opponent has full memory access) and to take a reference to it,” but I am not sure it could reasonably apply to anything due to the truncation issue. Do you have cases where you're 100% sure to be doing the right thing? Even As for where the traits should live, to be honest, I don't really think the most basic traits to interprocess communication should have any dependency or any code besides the most minimal one, as they ideally would end up in |
Yes, our use-case is slightly different, it's the inter-process communication in Servo, where different processes correspond to different security domains. Ideally even if an attacker compromised one of the security domains, they wouldn't be able to compromise the others, which is why we're worried about attackers being able to write into shared memory. We're also concerned about attackers being able to truncate shared memory, but there's not much we can do about that on non-Linux OSs.
Truncation is a real pain, ignoring it there are perfectly good types that are |
Looks like I had misunderstood your code, then, thank you for the correction. I guess the biggest issue I am having with As such, I'd expect any communication with an adversary to happen over a channel that transmits raw bytes, and to happen with serializing and deserializing, so that errors are handled properly anyway -- having the channel be implemented with volatile writes/reads on memory would then just be an implementation detail. In case that's the way you want to go, there's a crate we should be open-sourcing soon, that provides a ringbuffer in shared memory. Its threat model was also designed with cooperative processes in mind, but off the top of my head it should not lead to UB with an adversary -- assuming a few additions to the API are made, to return a pointer instead of a reference at a few places, and to allow pushing multiple values at once for optimization purposes if you're going the |
@Ekleog For structs, I was hoping to be able to derive For enums I wote some notes at https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=646c26558c0844392716497ba6c549e6, the rough idea being to only support Part of the aim here is to avoid the serialization/deserialization that ipc-channel currently uses, and provide zero-copy ipc channels. Servo currently uses shared memory for byte arrays as a special case to move images around without copying, it would be nice if that wasn't a special case any more. Your ring buffer looks really interesting, you can see the first shot I made at channels at https://github.com/asajeffrey/shared-data/blob/master/src/shared_channel.rs, the main difference AFAICT is that Servo needs unbounded channels (our deadlock-freedom properties depend on that). |
@asajeffrey What about passing types marked by the trait StableABI? The lib is a little on the heavy side, but essentially you can |
It's not obvious what the safety properties of
SharedSync
are expected to be. In particular, ifT
isSharedSync
, is it safe to take an&T
into shared memory? If so, what is the attacker model, can the attacker write into the shared memory? Can they truncate the shared memory?The text was updated successfully, but these errors were encountered: