Live data from Hacker News

-fbounds-safety: Enforcing bounds safety for C

clang.llvm.org

71–80 of 129 posts

Re: -fbounds-safety: Enforcing bounds safety for C

#71
post #36
post #34

Earlier quoted context omitted.

table stakes, but people still mess up on it constantly. The "yeah, but that's only a problem if you're an idiot" approach to this kind of thing hasn't served us very well so it's good to see something actually being done. Trains shouldn't collide if the driver is correctly observing the signals, that's table stakes too. But rather than exclusively focussing on improving track to reduce derailments we also install tr…

I'm not saying it's not important, it is. I just don't believe that '[the] majority of memory bugs are from out of bounds access'. That was maybe true 20 years ago, when an unbounded strcpy to an unprotected return pointer on the stack was super common and exploiting this kind of vulnerabilities what most vulndev was. This brings C one tiny step closer to the state of the art, which is commendable, but I don't believ…

The majority of security vulnerabilities in languages like C that aren’t memory safe are due to memory safety issues like UAF, buffer overflows etc etc. I don’t think I’ve seen finer grained research that tries to break it out by class of memory safety issue. The data is something like 80% of reported vulnerabilities in code written in these languages are due to memory safety issues. This doesn’t mean there aren’t other issues. It just means that it’s the cheapest exploit to search for when you are trying to break into a C/C++ service.

And in terms of how easy it is to convert a memory safety issue into an exploit, it’s not meaningfully much harder. The harder pieces are when sandboxing comes into play so that for example exploiting V8 doesn’t give you arbitrary broader access if the compromised process is itself sandboxed.

Re: -fbounds-safety: Enforcing bounds safety for C

#72

> 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 m…

I would imagine variables that are passed to functions would be considered ABI-visible. If the compiler is smart enough, it can keep the pointer wide when it’s passed to a function that’s also being compiled and act accordingly on the other side, but that worries me because this new meaning of “pointer” is propagating to parts of the code that might not necessarily agree with it.

Re: -fbounds-safety: Enforcing bounds safety for C

#73

> 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 m…

I don't understand this example: you're taking an address of local-scope stack object, storing it into a global list, and then use this address elsewhere in the code, possibly at different time-point, to manipulate with the object? I am obviously missing something because this cannot work unless this object lives on the stack of main().

Re: -fbounds-safety: Enforcing bounds safety for C

#74
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);

Re: -fbounds-safety: Enforcing bounds safety for C

#75
post #62
post #11

Earlier quoted context omitted.

It is called Solaris, and has this enabled since 2015 on SPARC. https://docs.oracle.com/en/operating-systems/solaris/oracle-...

Might as well not even talk about anything with the Oracular kiss of death.

Isn’t Illumos and OpenIndiana doing the same?

I still remember someone at Sun commented they treated warnings as errors. This is how software should be developed.

Re: -fbounds-safety: Enforcing bounds safety for C

#76

Earlier quoted context omitted.

I've been programming for long; the ratio of memory errors to logic bugs in production is so low as to be non-existent. My last memory error in C code in production was in 2018. Prior to that it I had a memory error in C code in production in 2007 or 2008. In C++, I eventually gave up trying to ship the same level of quality and left the language altogether.

The wider industry data gathered indicates that for memory unsafe languages 80% of issues are due to memory vulnerabilities, including mature codebases like Linux kernel, curl, V8, Chrome, Mach kernel, qemu etc etc etc. This doesn’t mean that logic bugs are less common, it just means that memory safety issues are the easiest way to get access. As for why your experience may be different, my hunch is that either your…

> The wider industry data gathered indicates that for memory unsafe languages 80% of issues are due to memory vulnerabilities, including mature codebases like Linux kernel, curl, V8, Chrome, Mach kernel, qemu etc etc etc.

You are misremembering the various reports - the reports were not that 80%[1] of issues were due to memory errors, but more along the lines of 80% of exploits were due to memory errors.

You could have 1000 bugs, with 10 of them being vulnerabilities, and 8 of those 10 being due to memory errors, and that would still be in line with the reports.

> As for why your experience may be different, my hunch is that either your code was super simple OR you didn’t test it thoroughly enough against malicious/unexpected inputs OR you never connected the code to untrusted I/O.

Payments processing, telecoms and munitions control software.

Of those, your explanation only applies to Telecoms; payments processing (EMV) was basically a constant stream of daily attacks, while munitions are live, in the field, with real explosives. We would've noticed any bugs, not just memory error bugs with the munitions one.

--------------------

[1] The number wasn't 80% IIRC, more like 70%?

Re: -fbounds-safety: Enforcing bounds safety for C

#77

> 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 m…

I don't understand this example: you're taking an address of local-scope stack object, storing it into a global list, and then use this address elsewhere in the code, possibly at different time-point, to manipulate with the object? I am obviously missing something because this cannot work unless this object lives on the stack of main().

Yep, it's a straight up error in C to return the address of a local variable from a function outside of main. Valgrind will flag this as use of an uninitialized value.

The problem is that as long as it's something where the calling function checks it immediately after the function exits and never looks again (something like an error code or choosing a code path based on the result) they often get away with it, especially in single threaded code.

I'm running into this at this very moment as I'm trying to make my application run cleanly, but some of the libraries are chock full of this pattern. One big offender is the Unix port of Microsoft's ODBC library, at least the Postgre integration piece.

I also blame the Unix standard library for almost having this pattern but not quite. Functions that return some kind of internal state that the programmer is told not to touch. Later they had to add a bunch of _r variants that were thread safe. The standard library functions don't actually have this flaw due to how they define their variables, but from the outside it looks like they do. It makes beginning programmers think that is how the functions should work and write their code in a similar manner.

Re: -fbounds-safety: Enforcing bounds safety for C

#78

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);

counted_by for struct fields actually is actually the part that afaik works today: https://embeddedor.com/blog/2024/06/18/how-to-use-the-new-co...

Re: -fbounds-safety: Enforcing bounds safety for C

#79

> 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 m…

I don't understand this example: you're taking an address of local-scope stack object, storing it into a global list, and then use this address elsewhere in the code, possibly at different time-point, to manipulate with the object? I am obviously missing something because this cannot work unless this object lives on the stack of main().

The best example I know of off the top of my head is wait_event() in Linux.

So long as the thread is guaranteed not to exit while blocked, you know its stack, and therefore the object allocated on it, must continue to exist. So, as long as there is no way to wake the thread except by kicking that object, the memory backing it is guaranteed to continue to exist until that object is kicked. You do have to somehow serialize the global data structure lookup (e.g. lock/dequeue/unlock/kick), if multiple threads can find and kick the object concurrently that's unsafe (the thread might exit between the first and subsequent kicks).

Generally that's true, even in pthread userspace: while there are some obvious artificial counterexamples one can construct, real world code very rarely does things like that.

Re: -fbounds-safety: Enforcing bounds safety for C

#80

Earlier quoted context omitted.

I don't understand this example: you're taking an address of local-scope stack object, storing it into a global list, and then use this address elsewhere in the code, possibly at different time-point, to manipulate with the object? I am obviously missing something because this cannot work unless this object lives on the stack of main().

Yep, it's a straight up error in C to return the address of a local variable from a function outside of main. Valgrind will flag this as use of an uninitialized value. The problem is that as long as it's something where the calling function checks it immediately after the function exits and never looks again (something like an error code or choosing a code path based on the result) they often get away with it, especi…

> Yep, it's a straight up error in C to return the address of a local variable from a function

Sure, that's true, but nobody is suggesting returning the address of a local variable anywhere in this thread.

I'm describing putting a pointer to a local variable in a global data structure, which is safe so long as the function doing it is somehow guaranteed not to return until the pointer is removed from the global data structure.

Post reply on HN