There is a way to sandbox native code without forking to a new process, and it looks like this https://hacks.mozilla.org/2020/02/securing-firefox-with-weba... Firefox employs processes for sandboxing but for small components they are not worth the overhead. For those they employed this curious idea: first compile the potentially unsafe code to wasm (any other VM would work), then compile the wasm code to C (using the…
You can skip all this nonsense with -fsanitize=undefined
Show HN: I built a Rust crate for running unsafe code safely
61–70 of 72 posts
Re: Show HN: I built a Rust crate for running unsafe code safely
#62Earlier quoted context omitted.
Why do you think this? The closest thing in “common” Rust would be unwraps/panics, but these are (1) not crashes per se, and (2) probably not more common than they would be in an equivalent C codebase.
"Panics are not crashes" is a new one. I'm referring to the fact that the rust code panics at the slightest sign of discomfort. And they are very much more common than in most C codebases. C codebases are generally often overly permissive in what they accept (hence to security bugs). Rust made a different trade.
That's kind of up to you as the developer though. I generally avoid writing functions that can panic -- I'd even argue any non-test code that panics is simply poorly written, because you can't "catch" a panic like you can in a high-level language. Better to return an error result and let the calling code decide how to handle it. Which often means showing an error to the user, but that's better than an unexpected crash.
Re: Show HN: I built a Rust crate for running unsafe code safely
#63this seems like a good place to ask, I don’t write very much unsafe Rust code… but when I do, it’s because I’m calling the Win32 API. Tools like valgrind do not work on windows, and I am nowhere near smart enough to know the entire layout of memory that should exist. When using Windows and calling system system functions, there’s a lot of casting involved; to convert wide characters and DWORDS to rust primitives for…
> I don’t write very much unsafe Rust code… but when I do, it’s because I’m calling the Win32 API. Check out windows-rs instead. https://github.com/microsoft/windows-rs
In my case I am looking for NetUserAdd and associated functionality, which doesn’t exist in any wrapper crate I could find- since that would have been significantly easier than what I ended up needing to do.
But, how do they test their unsafe bits?
Re: Show HN: I built a Rust crate for running unsafe code safely
#64Earlier quoted context omitted.
that’s what I’m doing already, the issue is that unsafe code exists at all. In order to call the win32 API one must create structs and pass pointers to them into the function call. sending data is actually quite easy. But reading back data is quite difficult, in some cases you may have a list of something. Regardless, Rust is not helping me anymore in those bits, and since all of the tools that find memory issues tar…
The Win32 API's object model is (mostly) compatible with Rust's. Handles play well with OBRM. Does the winsafe crate provide the interfaces you need? https://docs.rs/winsafe/
I was looking for NetUserAdd and associated commands.
Re: Show HN: I built a Rust crate for running unsafe code safely
#65Earlier quoted context omitted.
Why do you think this? The closest thing in “common” Rust would be unwraps/panics, but these are (1) not crashes per se, and (2) probably not more common than they would be in an equivalent C codebase.
"Panics are not crashes" is a new one. I'm referring to the fact that the rust code panics at the slightest sign of discomfort. And they are very much more common than in most C codebases. C codebases are generally often overly permissive in what they accept (hence to security bugs). Rust made a different trade.
In this context, I'm using "crash" to mean something like a program fault, i.e. an uncontrolled termination orchestrated by the kernel rather than the program itself. Rust programs generally terminate in a controlled manner, even if that manner is analogous to an unchecked exception.
It's also not my experience that Rust code, on average, panics on abnormal inputs. I've seen it happen, but the presence of e.g. safe iterators and access APIs means that you see a lot less of the "crash from invalid offset or index" behavior you see in C codebases.
(However, as pointed out in the adjacent thread, none of this really has anything to do with what "safe" means in Rust; controlled termination is one way to preserve safety, but idiomatic Rust codebases tend to lean much more heavily in the "error and result types for everything" direction. This in and of itself is arguably non-ideal in some cases.)
Re: Show HN: I built a Rust crate for running unsafe code safely
#66Earlier quoted context omitted.
"Panics are not crashes" is a new one. I'm referring to the fact that the rust code panics at the slightest sign of discomfort. And they are very much more common than in most C codebases. C codebases are generally often overly permissive in what they accept (hence to security bugs). Rust made a different trade.
> I'm referring to the fact that the rust code panics at the slightest sign of discomfort. That's kind of up to you as the developer though. I generally avoid writing functions that can panic -- I'd even argue any non-test code that panics is simply poorly written, because you can't "catch" a panic like you can in a high-level language. Better to return an error result and let the calling code decide how to handle it…
It is entirely up to you as the developer to write memory-safe code in C, and it's possible to do so. Most programmers don't because it's hard to do that once you're doing anything nontrivial. It's also possible to write panic-free rust, but it's hard.
Re: Show HN: I built a Rust crate for running unsafe code safely
#67This is likely to violate async-signal-safety [1] in any non-trivial program, unless used with extreme care. Running code in between a fork() and an exec() is fraught with peril; it's not hard to end up in a situation where you deadlock because you forked a multi-threaded process where one of the existing threads held a lock at the time of forking, among other hazards. [1] https://man7.org/linux/man-pages/man7/signal…
I'm adding a few more limitations in this PR: https://github.com/brannondorsey/mem-isolate/pull/44
I know async-signal-safety is particularly important for, you know, signal handlers. But aside from those, and the multi-threading use case you describe, is there another use case where calling non async-signal-safe code from inside this module would lead to issues (that isn't covered in the new limitations)?
I can add another limitation is issues can transpire if the code you run in `callable()` isn't async-signal-safe, but I'd like to offer a few additional examples of gotchas or surprises to point out there.
Re: Show HN: I built a Rust crate for running unsafe code safely
#68Please please please add a big huge warning to your crate that it should never be used in multi-threaded programs. fork() is not safe when there is more than one thread present, as the child process can easily deadlock (or worse) if the fork() happens at just the wrong time with respect to what other threads are doing.
Let me know if you think this wording could be improved or I'm missing any details.
Re: Show HN: I built a Rust crate for running unsafe code safely
#69I don't think this meets the definition of "safe" in "safe" Rust: "safe" doesn't just mean "won't crash due to spatial memory errors," it means that the code is in fact spatially and temporally memory safe. In other words: this won't detect memory unsafety that doesn't result in an abnormal exit or other detectable fault. If I'm writing an exploit, my entire goal is to perform memory corruption without causing a faul…
Let me know what you think, or if you have any additional suggestions.
Re: Show HN: I built a Rust crate for running unsafe code safely
#70I don't think this meets the definition of "safe" in "safe" Rust: "safe" doesn't just mean "won't crash due to spatial memory errors," it means that the code is in fact spatially and temporally memory safe. In other words: this won't detect memory unsafety that doesn't result in an abnormal exit or other detectable fault. If I'm writing an exploit, my entire goal is to perform memory corruption without causing a faul…
I've proposed these changes to shy away from the claims of "Run unsafe code safely" in this crate. Let me know what you think, or if you have any additional suggestions.