Live data from Hacker News

How safe is Zig?

scattered-thoughts.net

71–80 of 259 posts

Re: How safe is Zig?

#71
post #44
post #36

Earlier quoted context omitted.

There should but there aren't, GCC had a couple of extensions on a branch like 20 years ago that never got merged. The best is to use C++ instead, with bounds checked library types.

You can already get some bounds checking, although more work is needed: https://godbolt.org/z/abx7KE44z

Yeah, indeed. Thanks for sharing it.

Re: How safe is Zig?

#72
post #52

Earlier quoted context omitted.

I think the big question is, whether two teams writing software on a fixed budget using Rust or C using modern tools and best practices would end up with a safer product. I think this is not clear at all.

People have done just that with, for example, Firefox components and found that yes, Rust gives you a safer product.

Do you have a pointer? I know they rewrote Firefox components, but I am not aware of a real study with a 1:1 comparison.

Re: How safe is Zig?

#73
post #2

And here is the table with Nim added; though potentially many GC'd languages would be similar to Nim: https://uploads.peterme.net/nimsafe.html Edit: noteworthy addendum: the ARC/ORC features have been released, so the footnote is now moot.

Seeing Nim danger made me think, shouldn’t rust unsafe be added?

Seems inaccurate to display rust as safe and not include what actually allows memory bugs to be found in public crates.

Re: How safe is Zig?

#74
post #64
post #60

Earlier quoted context omitted.

Has an exploitable buffer bleed (I'm happy with this coinage!) happened in any recent memory safe codebase?

I worked on a static analysis tool to detect bleeds in outgoing email attachments, looking for non-zero padding in the ZIP file format. It caught different banking/investment systems written in memory safe languages leaking server RAM. You could sometimes see the whole intranet web page, that the teller or broker used to generate and send the statement, leaking through. Bleeds terrify me, no matter the language. The…

I am skeptical until I see the details, and strongly suspect you are dealing with a "safe-ish" language rather than one which has Rust-level guarantees. Uninitialized memory reads are undefined behavior in basically all memory models in the C tradition. In Rust it is not possible to make a reference to a slice containing uninitialized memory without unsafe (and the rules around this have tightened relatively recently, see MaybeUninit).

I say this as someone who is doing a lot of unsafe for graphics programming - I want to be able to pass a buffer to a shader without necessarily having zeroed out all the memory, in the common case I'm only using some of that buffer to store the scene data etc. I have a safe-ish abstraction for this (BufWriter in piet-gpu, for the curious), but it's still possible for unsafe shaders to do bad things.

Re: How safe is Zig?

#75
post #68
post #64

Earlier quoted context omitted.

I worked on a static analysis tool to detect bleeds in outgoing email attachments, looking for non-zero padding in the ZIP file format. It caught different banking/investment systems written in memory safe languages leaking server RAM. You could sometimes see the whole intranet web page, that the teller or broker used to generate and send the statement, leaking through. Bleeds terrify me, no matter the language. The…

You have my attention!

Wow, that's saying something!

The tool is called Pure [1]. It was originally written in JavaScript and open-sourced, then rewritten for Microsoft in C at their request for performance (running sandboxed) after it also detected David Fifield's “A Better Zip Bomb” as a zero day.

I'd love to rewrite it in Zig to benefit from the checked arithmetic, explicit control flow and spatial safety—there are no temporal issues for this domain since it's all run-to-completion single-threaded.

Got to admit I'm a little embarrassed it's still in C!

[1] https://github.com/ronomon/pure

Re: How safe is Zig?

#76
post #63

Earlier quoted context omitted.

But if you have a structure that contains offsets into another buffer somewhere, or an index, whatever - the wrong value here could be just as bad as a use-after-free. I don’t see how this is any safer. If you use memory after free from a malloc, with any chance you’ll hit a page fault, and your app will crash. If you have a index/pointer to another structure, you could still end up reading past the end of that struc…

That's just a logic error, and not memory unsafety which might risk UB or vulnerabilities. The type system enforces that if we use-after-"free" (remember, we're not free'ing or malloc'ing), we just get a different instance of the same type, which is memory-safe. You do bring up a valid broader concern. Ironically, this is a reason that GC'd systems can sometimes be better for privacy than Ada or Rust which uses a lot…

In high integrity computing that is pretty much safety related, if that logic error causes someone to die due to corrupt data, like using the wrong radiation value.

Re: How safe is Zig?

#77

Earlier quoted context omitted.

I'd consider even 10% to be a significant performance hit. People scream bloody murder when CPU-level mitigations cause even 1-2% regressions. The marginal cost of mitigations when memory safe code can run without them is infinite. But let's say, for the sake of argument, that I can tolerate programs that run twice as long in production. This doesn't improve much: * I'm not going to be deploying SoTA sanitizers (SANR…

I think we basically agree. Hypothetically ideal memory safety is strictly better, but sanitizers are better than nothing for code using fundamentally unsafe languages. My personal experience is that more people are dissuaded from sanitizer usage more by hypothetical (and manageable) issues like overhead than real implementation problems.

If you can afford a 10-50% across-the-board performance reduction, why would you not use a higher-level, actually safe language like Ruby or Python? Remember that the context of this article is Zig vs other languages, so the assumption is you’re writing new code.

Re: How safe is Zig?

#78

Do compilers really can never call `free()`? Simple compiler probably can. Most complex probably cannot (I don't want to imagine a Rust compiler without freeing memory: it has 7 layers of lowering (source code->tokens->ast->HIR->THIR->MIR->monomorphized MIR, excluding the final LLVM IR) and also allocates a lot while type-checking or borrow-checking). What is most interesting to me is the average compiler. Does someb…

LLVM uses a mixed strategy: there's both RAII and lots of globally allocated context that only gets destroyed at program cleanup. I believe GCC is the same. Rustc is written entirely in Rust, so I would assume that it doesn't do that.

The headline feature of rustc memory management is the use of arenas: https://github.com/rust-lang/rust/blob/10f4ce324baf7cfb7ce2b...

    //! The arena, a fast but limited type of allocator.
    //!
    //! Arenas are a type of allocator that destroy the objects within, all at
    //! once, once the arena itself is destroyed. They do not support deallocation
    //! of individual objects while the arena itself is still alive. The benefit
    //! of an arena is very fast allocation; just a pointer bump.
The other thing (not specifically mentioned in this comment, but mentioned elsewhere, and important to understanding why it work the way it does) is that if everything in the arena gets freed at once, it implies that you can soundly treat everything in the arena as having exactly the same lifetime.

You can see an example of how every ty::Ty in rustc winds up with the same lifetime, and an entry point for understanding it more, here in the dev guide: https://rustc-dev-guide.rust-lang.org/memory.html

However, arena allocation doesn't cover all of the dynamic allocation in rustc. Rustc uses a mixed strategy: there's both RAII and lots of arena allocated context that only gets destroyed at the end of a particular phase.

Re: How safe is Zig?

#79

Do compilers really can never call `free()`? Simple compiler probably can. Most complex probably cannot (I don't want to imagine a Rust compiler without freeing memory: it has 7 layers of lowering (source code->tokens->ast->HIR->THIR->MIR->monomorphized MIR, excluding the final LLVM IR) and also allocates a lot while type-checking or borrow-checking). What is most interesting to me is the average compiler. Does someb…

> Do compilers really can never call `free()`?

If a compiler has to be run multiple times in the same process, it may use an area allocator to track all memory, so you can free it all in one go once you're done with compilation. Delaying all freeing until the end effectively eliminates temporal memory issues.

Re: How safe is Zig?

#80

Earlier quoted context omitted.

LLVM uses a mixed strategy: there's both RAII and lots of globally allocated context that only gets destroyed at program cleanup. I believe GCC is the same. Rustc is written entirely in Rust, so I would assume that it doesn't do that.

The headline feature of rustc memory management is the use of arenas: https://github.com/rust-lang/rust/blob/10f4ce324baf7cfb7ce2b... //! The arena, a fast but limited type of allocator. //! //! Arenas are a type of allocator that destroy the objects within, all at //! once, once the arena itself is destroyed. They do not support deallocation //! of individual objects while the arena itself is still alive. The benefi…

Yep -- arenas compose very nicely with lifetimes, and basically accomplish the same thing as global allocation (in effect, a 'static arena) but with more control.
Post reply on HN