Live data from Hacker News

Unsafe Zig Is Safer Than Unsafe Rust

andrewkelley.me

41–50 of 105 posts

Re: Unsafe Zig Is Safer Than Unsafe Rust

#41
post #9

Earlier quoted context omitted.

There's not only a pedagogical task here, but the Rust community must learn how to write code safely. The major difficulty here is that in general, unsafe pieces of code cannot be safely composed, even if the unsafe pieces of code are individually safe. This allows you to bypass runtime safety checks without unsafe code just by composing "safe" modules that internally use unsafe code in their implementation. This kin…

> The major difficulty here is that in general, unsafe pieces of code cannot be safely composed, even if the unsafe pieces of code are individually safe. This allows you to bypass runtime safety checks without unsafe code just by composing "safe" modules that internally use unsafe code in their implementation. This comment suggests you don't have much domain knowledge about how `unsafe` in Rust works, so I'm surprise…

> This comment suggests you don't have much domain knowledge about how `unsafe` in Rust works, so I'm surprised you speak with such confidence.

I hate being tone police, but jeez, we're having a discussion about Rust here and talking about my personal competency is inappropriate and unwelcome.

The problem I'm talking about happens when you write libraries that contain "unsafe" blocks. You want to prove (or at least assure yourself) that no unsafe behavior is observable by clients of the library. However, the way to do this is not entirely clear, although there is research being done in this area. One known trap is that it is not sufficient to demonstrate that Rust code without "unsafe" blocks cannot observe unsafe behavior in your library.

See: https://plv.mpi-sws.org/rustbelt/popl18/paper.pdf

These concerns are not hypothetical, there have been soundness problems in the Rust standard library before and I expect it to happen again.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#42
post #38

Earlier quoted context omitted.

Its possible that I misread the comment; it seemed to state that this problem extended into safe Rust, which it definitely does not.

Think of two libraries that use unsafe Rust and interact with the same hardware, but work correctly when used on their own. A program written only in pure not-unsafe Rust might use these two libraries in a way that breaks because the assertions the programmers of the libaries had, like for example having exclusive access to the hardware, are wrong now. One could argue the pure not-unsafe Rust program is wrong, not th…

There is a conflation happening here. What is the nature of this bug when you compose these two libraries together?

If it is a violation of Rust's safety guarantees, then at least one of those libraries has a bug, it is exposes a safe abstraction which is not actually safe. One could not argue that the safe Rust program is wrong; the library exposing an unsafe interface as safe is unarguably wrong.

If the library just behaves incorrectly in a manner disconnected from the type system because some global state was changed in a way it doesn't expect ("the hardware" in this case), then that's a normal bug & it is not connected to unsafe code at all.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#43
post #38

Earlier quoted context omitted.

Think of two libraries that use unsafe Rust and interact with the same hardware, but work correctly when used on their own. A program written only in pure not-unsafe Rust might use these two libraries in a way that breaks because the assertions the programmers of the libaries had, like for example having exclusive access to the hardware, are wrong now. One could argue the pure not-unsafe Rust program is wrong, not th…

There is a conflation happening here. What is the nature of this bug when you compose these two libraries together? If it is a violation of Rust's safety guarantees, then at least one of those libraries has a bug, it is exposes a safe abstraction which is not actually safe. One could not argue that the safe Rust program is wrong; the library exposing an unsafe interface as safe is unarguably wrong. If the library jus…

> then at least one of those libraries has a bug

Yes, we agree about this point. However, the process for determining if these bugs exist is not well understood. That's what I mean when I say that this is not only a pedagogical problem--even Rust experts struggle to prove that a library containing "unsafe" blocks is safe, and more research into the area is needed.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#44

Earlier quoted context omitted.

> The major difficulty here is that in general, unsafe pieces of code cannot be safely composed, even if the unsafe pieces of code are individually safe. This allows you to bypass runtime safety checks without unsafe code just by composing "safe" modules that internally use unsafe code in their implementation. This comment suggests you don't have much domain knowledge about how `unsafe` in Rust works, so I'm surprise…

> This comment suggests you don't have much domain knowledge about how `unsafe` in Rust works, so I'm surprised you speak with such confidence. I hate being tone police, but jeez, we're having a discussion about Rust here and talking about my personal competency is inappropriate and unwelcome. The problem I'm talking about happens when you write libraries that contain "unsafe" blocks. You want to prove (or at least a…

Proving the correctness of unsafe code is totally different from what you talked about, which was composing different abstractions with unsafe internals together.

Users of safe Rust do not need to worry about whether the composition of two safe interfaces that use unsafe internally is safe unless one of those interfaces is incorrect. Your comment would suggest that users need to think about the untyped invariants of each library they use, but this is not correct, libraries are not allowed to rely on untyped invariants for the correctness of their safe APIs.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#45

Earlier quoted context omitted.

There is a conflation happening here. What is the nature of this bug when you compose these two libraries together? If it is a violation of Rust's safety guarantees, then at least one of those libraries has a bug, it is exposes a safe abstraction which is not actually safe. One could not argue that the safe Rust program is wrong; the library exposing an unsafe interface as safe is unarguably wrong. If the library jus…

> then at least one of those libraries has a bug Yes, we agree about this point. However, the process for determining if these bugs exist is not well understood. That's what I mean when I say that this is not only a pedagogical problem--even Rust experts struggle to prove that a library containing "unsafe" blocks is safe, and more research into the area is needed.

My apologies if I misunderstood you - I read your comment as suggesting that safe abstractions are "leaky" and therefore create additional responsibilities for users to validate that they are using them safely when composing them together. This is not the case unless those abstractions are incorrect - which is the same situation you are with any language, just most languages those abstractions exist within the language runtime & not in libraries.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#46

Earlier quoted context omitted.

> The major difficulty here is that in general, unsafe pieces of code cannot be safely composed, even if the unsafe pieces of code are individually safe. This allows you to bypass runtime safety checks without unsafe code just by composing "safe" modules that internally use unsafe code in their implementation. This comment suggests you don't have much domain knowledge about how `unsafe` in Rust works, so I'm surprise…

> This comment suggests you don't have much domain knowledge about how `unsafe` in Rust works, so I'm surprised you speak with such confidence. I hate being tone police, but jeez, we're having a discussion about Rust here and talking about my personal competency is inappropriate and unwelcome. The problem I'm talking about happens when you write libraries that contain "unsafe" blocks. You want to prove (or at least a…

> One known trap is that it is not sufficient to demonstrate that Rust code without "unsafe" blocks cannot observe unsafe behavior in your library.

I'm curious: what does this mean/could you point me to the part of the paper that describes it? (Unfortunately, I don't have time to read all 34 pages at the moment.)

Re: Unsafe Zig Is Safer Than Unsafe Rust

#47
post #27

Earlier quoted context omitted.

Correct me if I’m wrong but I thing GP was stating that composing two “unsafe” blocks together (both of which are manually verified to work well) might interfere with each other when run simultaneously.

'unsafe' doesn't mean unsafe. Unsafe means "I can't convince the compiler that this is safe. But in my context, it is." If there is any way in which a function containing an `unsafe` block may be used unsafely (specifically, violating memory-safety), then that function must also be marked as unsafe.

That's what it means if you use it properly. If you write bad code, it means "this code will break everything and the compiler won't protect you." An `unsafe` block does nothing to guarantee that you're doing something safe, which is what you seem to be saying, even if it's not what you mean to say.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#48
post #29

I'd like to see a C equivalent of this, just for comparisons sake to zig

#include #include typedef struct { int32_t a; int32_t b; } Foo; int main(void) { uint8_t array[1024]; memset(array, 1, sizeof(array)); Foo *foo = (Foo*)(&array[0]); foo->a += 1; } Using clang 3.8.0-2. Compiling examples with `clang -S llvm-ir`. It appears that the array is aligned with the minimum ABI requirement 16 by default? May be a note of this in the standard, can't recall of the top of my head. %array = alloca…

On 64bit Linux, stack frames are always aligned at 16 byte boundaries. The first 8 bytes of the frame contains the return address then there are 8 bytes of padding and then comes the stack allocations.

I think the example is poorly constructed, because it is inconceivable that the address to the start of an array would not be aligned sizeof(int*) bytes.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#49

One big glaring flaw IMO is that it is not really possible to just turn off certain checks as opposed to turning them all off. For instance, maybe I need to call an unsafe C api or something but could still use the borrow checker.

The Rust book clearly states:

"It’s important to understand that unsafe doesn’t turn off the borrow checker or disable any other of Rust’s safety checks" [1]

"unsafe" unlocks only 4 things: Dereferencing a raw pointer, Calling an unsafe function or method, Accessing or modifying a mutable static variable, Implementing an unsafe trait.

[1] https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe...

Re: Unsafe Zig Is Safer Than Unsafe Rust

#50
post #48
post #29

Earlier quoted context omitted.

#include #include typedef struct { int32_t a; int32_t b; } Foo; int main(void) { uint8_t array[1024]; memset(array, 1, sizeof(array)); Foo *foo = (Foo*)(&array[0]); foo->a += 1; } Using clang 3.8.0-2. Compiling examples with `clang -S llvm-ir`. It appears that the array is aligned with the minimum ABI requirement 16 by default? May be a note of this in the standard, can't recall of the top of my head. %array = alloca…

On 64bit Linux, stack frames are always aligned at 16 byte boundaries. The first 8 bytes of the frame contains the return address then there are 8 bytes of padding and then comes the stack allocations. I think the example is poorly constructed, because it is inconceivable that the address to the start of an array would not be aligned sizeof(int*) bytes.

The example is illustrative enough: all the array needs to be misaligned in practice is a small value on the stack near it, e.g. if the Rust code has `let x: u8 = 1;` inserted after the array (or, I imagine, `uint8_t x = 1;` in the C, etc.), then the array's address is odd.
Post reply on HN