27 comments

[ 2.6 ms ] story [ 49.5 ms ] thread
I want an OS distro where all C code is compiled this way.

OpenBSD maybe? or a fork of CheriBSD?

macOS clang has supported -fbounds-safety for a while, but I"m not sure how extensively it is used.

>I want an OS distro where all C code is compiled this way.

You first have to modify "all C code". It's not just a set and forget compiler flag.

You need to annotate your program with indications of what variable tracks the size of the allocation. So, sure, but first work on the packages in the distro.

Note that corresponding checks for C++ library containers can be enabled without modifying the source. Google measured some very small overhead (< 0.5% IIRC) so they turned it on in production. But I'd expect an OS distro to be mostly C.

[1] https://libcxx.llvm.org/Hardening.html

Get gentoo, add this to CFLAGS and start fixing everything that breaks. Become a hero.
does any distro uses clang? I thought all linux kernels were compiled using gcc.
Fedora and its kernels are built with GCC's _FORTIFY_SOURCE and I've seen modules crash for out of bounds reads.
Maybe this:

https://fil-c.org/pizlix

>Pizlix is LFS (Linux From Scratch) 12.2 with some added components, where userland is compiled with Fil-C. This means you get the most memory safe Linux-like OS currently available.

The author, @pizlonator, is active on HN.

I'm aware of Pizlix - it's a good project/idea that needs to go mainstream; as you mention, memory safety is currently limited to userland (still a huge improvement over traditional unsafe userland.)

Note also that it uses fil-c rather than clang with -fbounds-safety. I believe fil-c requires fewer code changes than -fbounds-safety.

  template <typename T>
  struct Slice {
      T* data = nullptr;
      size_t size = nullptr;

      T& operator[](size_t index) {
        if (index >= size) crash_the_program();
        return data[index];
      }
  };

If you're considering this extension, just use C++ and 5 lines of standard, portable, no-weird-annotations code instead.
this is amazing, counter to what most ppl think, majority of memory bugs are from out of bounds access, not stuff like forgetting to free a pointer or some such
Very cool. I always wondered why there isn't something like this in GCC/LLVM, it would obviously solve uncountable of security issues.
Has any progress been made on this? I remember seeing this proposal 3 or 4 years ago but it looks like it still hasn't been implemented. It's a shame because it seems like a useful feature. It looks like Microsoft has something similar (https://learn.microsoft.com/en-us/cpp/code-quality/understan...) but it would be nice to have something that worked on other platforms.
As I and others noted below, it is included in Apple's clang version, which is what you get when you install the command line tools for Xcode. Try something like:

    clang -g -Xclang -fbounds-safety program.c
Bounds check failures result in traps; in lldb you get a message like:

    stop reason = Bounds check failed: Dereferencing above bounds
The real question is adoption friction. The annotation requirement means this won't just slot into existing codebases — someone has to go through and mark up every buffer relationship. Google turning on libcxx hardening in production with <0.5% overhead is compelling precisely because it required zero source changes.

The incremental path matters more than the theoretical coverage. I'd love to see benchmarks on a real project — how many annotations per KLOC, and what % of OOB bugs it actually catches in practice vs. what ASAN already finds in CI.

Exciting! It doesn't imply that we should now sprinkle the new annotations everywhere. We still should keep working with proper iterators and robust data structures, and those would need to add such annotations.
Xcode (AppleClang) has had -fbounds-safety for a while now. What is the delay getting this into merged into LLVM?
> As local variables are typically hidden from the ABI, this approach has a marginal impact on it.

I'm skeptical this is workable... it's pretty common in systems code to take the address of a local variable and pass it somewhere. Many event libraries implement waiting for an event that way: push a pointer to a futex on the stack to a global list, and block on it.

They address it explicitly later:

> Although simply modifying types of a local variable doesn’t normally impact the ABI, taking the address of such a modified type could create a pointer type that has an ABI mismatch

That breaks a lot of stuff.

The explicit annotations seem like they could have real value for libraries, especially since they can be ifdef'd away. But the general stack variable thing is going to break too much real world code.

Niklaus Wirth died in 2024, and yet I hope he is having a major I-told-you-so moment about people blaming Pascal's bounds checking to be unneeded and making things slow.
My CS college used Turbo Pascal as a teaching language. I had a professor who told us "don't turn the range and overflow checking off, even when compiling for production". That turned out to be very wise advice, IMHO. Too bad C and C++ compiler/language designers never got that message. So much wasted to save that less than 1% performance gain.
Bounded strings turned out to be a fairly good idea as well.
Amazing, this is a life saving feature for C developers. Apparently it's not complete yet? I will apply this to my code once the feature is included on LLVM and GCC.

Would be nice if the annotations could also be applied to structure fields.

  struct bytes {
      size_t count;
      unsigned char * __counted_by(count) pointer;
  };

  void work_with(struct bytes);
> To tackle this issue, the model incorporates the concept of a “wide pointer” (a.k.a. fat pointer) – a larger pointer that carries bounds information alongside the pointer value.

Bounds checking with fat pointers existed as a set of patches for GCC in the early 2000's. (C front end only).

https://sourceforge.net/projects/boundschecking/