Live data from Hacker News

How safe is Zig?

scattered-thoughts.net

81–90 of 259 posts

Re: How safe is Zig?

#81
I have one trick up my sleeve for memory safety of locals. I'm looking forward to experimenting with it during an upcoming release cycle of Zig. However, this release cycle (0.10.0) is all about polishing the self-hosted compiler and shipping it. I'll be sure to make a blog post about it exploring the tradeoffs - it won't be a silver bullet - and I'm sure it will be a lively discussion. The idea is (1) escape analysis and (2) in safe builds, secretly heap-allocate possibly-escaped locals with a hardened allocator and then free the locals at the end of their declared scope.

Re: How safe is Zig?

#82

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…

For further reading, I recommend Niko's latest blog, tangentially related to rustc internals (and arena allocation): https://smallcultfollowing.com/babysteps/blog/2022/06/15/wha...

Re: How safe is Zig?

#83

Earlier quoted context omitted.

How exactly is pre-allocation safer? If you would ever like to re-use chunks of memory, then wouldn’t you still encounter “use-after-free” bugs?

The approach can reuse old elements for new instances of the same type, so to speak. Since the types are the same, any use-after-free becomes a plain ol' logic error. We use this approach in Rust a lot, with Vecs.

These are 1000 times worse than even a segfault. These are the bugs you won’t notice until they crop up at a wildly different place, and you will have a very hard time tracking it back to their origin (slightly easier in Rust, as you only have to revalidate the unsafe parts, but it will still suck)

Re: How safe is Zig?

#84

I like zig but this is taking a page out of rust book and exaggerating C and C++ clang and gcc will both tell you at runtime if you go out of bounds, have an integer overflow, use after free etc. You need to turn on the sanitizer. You can't have them all on at the same time because code will be unnecessarily slow (ex: having thread sanitizer on in a single threaded app is pointless)

Whoa the username checks out perfectly.

Haha yes. I love knowing I'm in bounds but unfortunately saying anything about C++ (that isn't a criticism) is out of bounds and my comment got downvoted enough that I don't feel like saying more

Re: How safe is Zig?

#85

A lot of embedded devices and safety critical software sometimes don't even use a heap, and instead use pre-allocated chunks of memory whose size is calculated beforehand. It's memory safe, and has much more deterministic execution time. This is also a popular approach in games, especially ones with entity-component-system architectures. I'm excited about Zig for these use cases especially, it can be a much easier ap…

Even in this environment, you can still have dangling pointers to freed stack frames. There's no way around having a proper lifetime system, or a GC, if you want memory safety.

Yep, or generational references [0] which also protect against that kind of thing ;)

The array-centric approach is indeed more applicable at the high levels of the program.

Sometimes I wonder if a language could use an array-centric approach at the high levels, and then an arena-based approach for all temporary memory. Elucent experimented with something like this for Basil once [1] which was fascinating.

[0] https://verdagon.dev/blog/generational-references

[1] https://degaz.io/blog/632020/post.html

Re: How safe is Zig?

#86

I’m not sure I understand the value of an allocator that doesn’t reuse allocations, as a bug prevention thing. Is it just for performance? (Since its never reused, allocation can simply be incrementing an offset by the size of the allocation)? Because beyond that, you can get the same benefit in C by simply never calling free on the memory you want to “protect” against use-after-free.

I believe it is only for performance, as malloc will have to find place for the allocation, while it is a pointer bump only for a certain kind of allocator.

Re: How safe is Zig?

#87

I like zig but this is taking a page out of rust book and exaggerating C and C++ clang and gcc will both tell you at runtime if you go out of bounds, have an integer overflow, use after free etc. You need to turn on the sanitizer. You can't have them all on at the same time because code will be unnecessarily slow (ex: having thread sanitizer on in a single threaded app is pointless)

Can you explain why, in spite of the fact that (according to you) C & C++ aren't that unsafe, critical projects like Chromium can't get this right? https://twitter.com/pcwalton/status/1539112080590217217 Is the Project Zero team just too lazy to remind Chromium to use sanitizers?

Considering how much I got downvoted no I don't want to comment more about this. But I'll let you ponder why while using rust has you could get a use after free sometimes https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-4572...

Re: How safe is Zig?

#88
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…

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…

Hackers exploit any avenue (and usually come in through the basement!), regardless of how skeptical we might be that they won't. They don't need the details, they'll figure it out. You give them a scrap and they'll get the rest. It's a different way of thinking that we're not used to, and don't understand unless we're exposed to it first-hand, e.g. through red-teaming.

For example, another way to think of this is that you have a buffer of initialized memory, containing a view onto some piece of data, from which you serve a subset to the user, but you get the format of the subset wrong, so that parts of the view leak through. That's a bleed.

Depending on the context, the bleed may be enough or it might be less severe, but the slightest semantic gap can be chained and built up into something major. Even if it takes 6 chained hoops to jump through, that's a low bar for a determined attacker.

Re: How safe is Zig?

#89
post #50
post #39

"Temporal" and "spatial" is a good way to break this down, but it might be helpful to know the subtext that, among the temporal vulnerabilities, UAF and, to an extent, type confusion are the big scary ones. Race conditions are a big ugly can of worms whose exploitability could probably be the basis for a long, tedious debate. When people talk about Zig being unsafe, they're mostly reacting to the fact that UAFs are s…

I see your UAF and raise you a bleed! As you know, buffer bleeds like Heartbleed and Cloudbleed can happen even in a memory safe language, they're hard to defend against (padding is everywhere in most formats!), easier to pull off than a UAF, often remotely accessible, difficult to detect, remain latent for a long time, and the impact is devastating. All your RAM are belong to us. For me, this can of worms is the one…

Would that work in the case of Java for example? It nulls every field as per the specification (at least observably at least), so unless someone writes some byte mangling manually I don’t necessarily see it work out.

Re: How safe is Zig?

#90
post #29

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()`? I worked on, one of the many, Microsoft compiler teams, though as a software engineer in test not directly on the compiler itself, and I believe the lead dev told me they don't free any memory, though I could be misremembering since it was my first job out of college. Remember C compilers are often one file at a time (and a LOLWTF # of includes), and the majority of work…

Bootstrapping aside, a compiler written in a GCd language would make perfect sense. It really doesn’t have any reason to go lower level than that (other than of course, if one wants to bootstrap it in the same language that happens to be a low-level one)
Post reply on HN