Live data from Hacker News

Show HN: I built a Rust crate for running unsafe code safely

github.com

11–20 of 72 posts

Re: Show HN: I built a Rust crate for running unsafe code safely

#11
I 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 fault; that's why Rust's safety property is much stronger than crash-freeness.

Re: Show HN: I built a Rust crate for running unsafe code safely

#14

Forking and this package can be useful if you know that the unsafe code is really unsafe and have no hope of making it better. But I wouldn't use this often. I'd be willing to bet that you'd lose all performance benefits of using Rust versus something like Python or Ruby that uses forking extensively for parallelism.

> have no hope of doing better

Yeah, this is really the main use case. Its a relatively simple solution when you can't do any better.

I think that's particularly helpful when you're invoking code you don't control, like calling into a some arbitrary C library.

Re: Show HN: I built a Rust crate for running unsafe code safely

#15
This isn't mentioned anywhere on the page, but fork is generally not a great API for these kinds of things. In a multi-threaded application, any code between the fork and exec syscalls should be async-signal-safe. Since the memory is replicated in full at the time of the call, the current state of mutexes is also replicated and if some thread was holding them at the time, there is a risk of a deadlock. A simple print! or anything that allocates memory can lead to a freeze. There's also an issue of user-space buffers, again printing something may write to a user-space buffer that, if not flushed, will be lost after the callback completes.

Re: Show HN: I built a Rust crate for running unsafe code safely

#16

I 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…

It's not just that it won't crash, it means that an exploit in the unsafe code won't allow corrupting memory used by the rest of the program

Re: Show HN: I built a Rust crate for running unsafe code safely

#17

I 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…

It's not just that it won't crash, it means that an exploit in the unsafe code won't allow corrupting memory used by the rest of the program

This is pretty immaterial from an exploit development perspective:

1. The forked process has a copy of the program state. If I'm trying to steal in-process secrets, I can do it from the forked process.

2. The forked process is just as privileged as the original process. If I'm trying to obtain code execution, I don't care which process I'm in.

This is why Chrome at al. have full-fledged sandboxes that communicate over restricted IPC; they don't fork the same process and call it a day.

Re: Show HN: I built a Rust crate for running unsafe code safely

#18
post #5

this 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…

The easy solution is, don't call system functions. Instead:

• Work out what you want to do, conceptually.

• Design a safe abstraction that would allow you to do that. (Consult the Win32 API documentation for concepts to use.)

• Implement that abstraction using the Win32 API.

That last step is way easier than trying to use the Win32 API throughout your program, you'll end up with significantly less unsafe code, and if anything does go wrong, it's much easier to fix.

Re: Show HN: I built a Rust crate for running unsafe code safely

#19

I 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…

Even better, this library, with its use of unsafe and fork underneath, introduces a whole new class of undefined behavior to a program by providing a safe interface over an unsafe API without actually enforcing the invariants necessary for safety.

In order for the fork() it calls to be safe, it needs to guarantee a bunch of properties of the program that it simply cannot. If this gets used in a multithreaded program that calls malloc, you've got UB. There's a long list of caveats with fork mentioned in some other comments here.

In my view, this is not serious code and should be regarded as a joke. There's no actual value in this type of isolation.

Re: Show HN: I built a Rust crate for running unsafe code safely

#20
post #5

this 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…

The easy solution is, don't call system functions. Instead: • Work out what you want to do, conceptually. • Design a safe abstraction that would allow you to do that. (Consult the Win32 API documentation for concepts to use.) • Implement that abstraction using the Win32 API. That last step is way easier than trying to use the Win32 API throughout your program, you'll end up with significantly less unsafe code, and if…

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 target primarily C++, and rust mangles certain things for C+ + toolchains - I find myself a little bit stuck, I’m not a genius and I’ll take all the help I can get.

Post reply on HN