Live data from Hacker News

How safe is Zig?

scattered-thoughts.net

31–40 of 259 posts

Re: How safe is Zig?

#31

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…

I presume he means that compilers could be written to never call `free()`. I'm sure that most of them are not written like that, though they do tend to be very leaky and just `exit()` at the end rather than clean everything up neatly (partly because it's faster).

Re: How safe is Zig?

#32

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.

Re: How safe is Zig?

#33
This is why for me, Zig is mostly a Modula-2 with C syntax in regards to safety.

All the runtime tooling it offers, already exists for C and C++ for at least 30 years, going back to stuff like Purify (1992).

Re: How safe is Zig?

#34
Question for Zig experts:

Is it possible, in principle, to use comptime to obtain Rust-like safety? If this was a library, could it be extended to provide even stronger guarantees at compile time, as in a dependent type system used for formal verification?

Of course, this does not preclude a similar approach in Rust or C++ or other languages; but comptime's simplicity and generality seem like they might be beneficial here.

Re: How safe is Zig?

#35

This was a great read, with an important point: there's always a tradeoff to be made, and we can make it (e.g. never freeing memory to obtain temporal memory safety without static lifetime checking). One thought: > Never calling free (practical for many embedded programs, some command-line utilities, compilers etc) This works well for compilers and embedded systems, but please don't do it command-line tools that are…

There are some old-hand approaches to this which work out fine. An example would be a generous rolling buffer, with enough room for the data you're working on. Most tools which are working on a stream of data don't require much memory, they're either doing a peephole transformation or building up data with filtration and aggregation, or some combination. You can't have a use-after-free bug if you never call free, tre…

Yeah, those are the approaches that I've used (back when I wrote more user tools in C). I wonder how those techniques translate to a language like Zig, where I'd expect the naive approach to be to allocate a new string for each line/datum (which would then never truly be freed, under this model.)

Re: How safe is Zig?

#36

UBSan has a -fsanitize-minimal-runtime flag which is supposedly suitable for production: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#... So it seems that null-pointer dereferences and integer overflows can be checked at runtime in C. Besides, there should be production-ready C compilers that offer bounds checking.

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.

Re: How safe is Zig?

#37

Earlier quoted context omitted.

Is that `wordcount` in Zig? My understanding (which could be wrong) is that reallocation in Zig would leave the old buffer "alive" (from the allocator's perspective) if it couldn't be expanded, meaning that you'd eventually OOM if a large enough contiguous region couldn't be found.

It's in zig but I just call mmap twice at startup to get one slab of memory for the whole file plus all the space I'll need. I am not sure whether Zig's GeneralPurposeAllocator or PageAllocator currently use mremap or not, but I do know that when realloc is not implemented by a particular allocator, the Allocator interface provides it as alloc + memcpy + free. So I think I would not OOM. In safe builds when using Gen…

That's interesting, thanks for the explanation!

Re: How safe is Zig?

#38

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)

Neither Clang nor GCC has perfect bounds or lifetime analysis, since the language semantics forbid it: it's perfectly legal at compile time to address at some offset into a supplied pointer, because the compiler has no way of knowing that the memory there isn't owned and initialized. Sanitizers are great; I love sanitizers. But you can't run them in production without a significant performance hit, and that's where t…

> it's perfectly legal at compile time to address at some offset into a supplied pointer, because the compiler has no way of knowing that the memory there isn't owned and initialized.

Embedded land, everything is a flat memory map, odds are malloc isn't used at all, memory is possibly 0'd on boot.

It is perfectly valid to just start walking all over memory. You have a bunch of #defines with known memory addresses in them and you can just index from there.

Fun fact: Microsoft Band writes crash dumps to a known location in SRAM and because SRAM doesn't instantly lose its contents on reboot, after a crash the runtime checks for crash dump data at that known address and if present would upload the crash dump to servers for analysis and then 0 out that memory.[1]

Embedded rocks!

[1] There is a bit more to it to ensure we aren't just reading random data after along power off, but I wasn't part of the design, I just benefited from a 256KB RAM wearable having crash dumps that we could download debugging symbols for.

Re: How safe is Zig?

#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 still viable in it.

Re: How safe is Zig?

#40

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)

What is the cause of all those notorious C bugs then?

[deleted]
Post reply on HN