Live data from Hacker News

OpenBSD – pinning all system calls

marc.info

21–30 of 118 posts

Re: OpenBSD – pinning all system calls

#22
post #18
post #15

Earlier quoted context omitted.

This just went out to tech@: https://marc.info/?l=openbsd-tech&m=170234892604404&w=2

One of the more under-appreciated features of Rust is that it traps on integer overflow / underflow by default. It’s too bad OpenBSD doesn’t have a good Rust story for the core system. (I understand their reasoning, but it’s still too bad.) I wonder how hard it would be to backport the integer behavior to C. (C++ would be easy: Use templates.) Perhaps they could add a compiler directive that causes vanilla integer ov…

> One of the more under-appreciated features of Rust is that it traps on integer overflow / underflow by default.

I think this is only true on debug builds, with --release (which most Rust binaries an end-user uses should be compiled with) it just wraps [1] [2]

[1] https://github.com/rust-lang/rfcs/blob/26197104b7bb9a5a35db2... [2] https://stackoverflow.com/a/60238510

Re: OpenBSD – pinning all system calls

#23
post #18
post #15

Earlier quoted context omitted.

This just went out to tech@: https://marc.info/?l=openbsd-tech&m=170234892604404&w=2

One of the more under-appreciated features of Rust is that it traps on integer overflow / underflow by default. It’s too bad OpenBSD doesn’t have a good Rust story for the core system. (I understand their reasoning, but it’s still too bad.) I wonder how hard it would be to backport the integer behavior to C. (C++ would be easy: Use templates.) Perhaps they could add a compiler directive that causes vanilla integer ov…

Look, I get as much as the next guy that Rust brings a lot of niceties. But what we are talking about here is a project that clocks in at just over 19,000,000 lines of C (`wc -l $(find src -name '*.c' -or -name '*.h')`), code heritage going back more than 40 years, an explicit commitment to a very rich set of platforms [1], and a very limited amount of manpower compared to projects such as Linux with their insane level of corporate backing. "Just rewrite it in and/or integrate Rust" is neither easy nor safe in that it overturns everything that is already there and tested.

[1]: https://www.openbsd.org/plat.html

As for improving upon C. I can not speak for OpenBSD as a project, but I am sure that there would be ample excitement to produce a minimal, solid C compiler with experimental security features to then serve as the default compiler for the project (heck, OpenBSD already ships with a number of less common security-related compiler flags from what I recall). Sadly, I doubt there is either funding or the hands to make that a reality.

Re: OpenBSD – pinning all system calls

#24

Earlier quoted context omitted.

The other comment on this thread mentions that it also does something else: >disables all the system calls not explicitly invoked by the program text of a static binary This means that if the original library didn't have an execve call in it, you would'nt be able to use it even if with ROP. In short, this seems useful to block attackers from using syscalls that were not originally used by the program and nothing else…

Sure, assuming your programs don't execute other programs. I don't know much about OpenBSD specifically, but spawning all over the place is the "norm" in terms of "Unix philosophy" program design. (I agree with the point in the adjacent thread: it's hard to know what to make of security mitigations that aren't accompanied by a threat model and attacker profile!)

> assuming your programs don't execute other programs.

What about language runtimes? They don't execute other programs in the sense of ELF executables (although the programs they interpret might), but they have to support every syscall that's included in the language. So, for example, the Python interpreter would have to include the appropriate code for every syscall that Python byte code could call (in addition to whatever internal syscalls are used by the interpreter itself). That would be a pretty complete set of syscalls.

Re: OpenBSD – pinning all system calls

#25
post #16
post #5

Earlier quoted context omitted.

Indeed, in CCC's "systematic evaluation of OpenBSD's mitigations"[0] the presenter explicitly calls out OpenBSD's tendency to present mitigations without specific examples of CVEs it defeats or exploit techniques the mitigations are known to defend against: > Proper mitigations I think stem from proper design and threat modeling. Strong, reality-based statements like "this kills these vulnerabilities," or "this kills…

There have been cases where OpenBSD's hypothetical mitigations have worked out well for the project. I recall a relatively recent DNS cache poisoning attack that OpenBSD was novel in pre-emptively mitigating because something (I think it was the port?) was "needlessly" random. If a mitigation has negligible performance impact, and doesn't introduce a new attack vector, I can't imagine why it would be seen as a bad th…

Every mitigation is code and complexity. There is always a cost.

Re: OpenBSD – pinning all system calls

#26
post #17

Earlier quoted context omitted.

Would you mind sharing how and where in the code, specifically. Geniunely curious.

I don't know how they define `MAX`, but I'm guessing it's a typical "a>b?a:b". In function `elf_read_pintable` the `npins` is defined as signed int and `sysno` as unsigned int. So this comparison will be unsigned and will allow to set `npins` to any value, even negative: npins = MAX(npins, syscalls[i].sysno) Then `SYS_kbind` seems to be a signed int. So this comparison will be signed and "fix" the negative `npins` to…

That seems about right.

Re: OpenBSD – pinning all system calls

#28
post #2

Classic thread on this stuff from Halvar Flake: https://twitter.com/halvarflake/status/1156815950873804800 With that in mind, it'd be handy to know which exploit techniques these steps break, and whether those steps are in the current "meta" game for exploit developers. (The specific mitigation here: the kernel formerly locked system call invocation down to the libc.so area of program text in memory; libc.so is big,…

Is there a current meta for OpenBSD exploit developers?

What's the right way to go about hardening the system if there's no meta to observe?

My very naive take would be something like: A successful exploit depends on jumping through a number of different hoops. Each of those hoops has an estimated success probability associated with it. We can multiply all the individual probabilities together to get an estimated probability of successful exploit -- assuming that hoop probabilities are independent, which seems reasonable? The most efficient way to harden against exploits is to try and shrink whichever hoop possesses the greatest partial derivative of overall exploit success probability with respect to developer time.

Re: OpenBSD – pinning all system calls

#29
post #24

Earlier quoted context omitted.

Sure, assuming your programs don't execute other programs. I don't know much about OpenBSD specifically, but spawning all over the place is the "norm" in terms of "Unix philosophy" program design. (I agree with the point in the adjacent thread: it's hard to know what to make of security mitigations that aren't accompanied by a threat model and attacker profile!)

> assuming your programs don't execute other programs. What about language runtimes? They don't execute other programs in the sense of ELF executables (although the programs they interpret might), but they have to support every syscall that's included in the language. So, for example, the Python interpreter would have to include the appropriate code for every syscall that Python byte code could call (in addition to w…

Yep, language runtimes are an (inevitably?) large attack surface. My understanding is that OpenBSD userspace processes can voluntarily limit their own syscall behavior with pledge[1], so a Python program (or the interpreter itself) could limit the scope of a particular process. But I have no idea how common that is.

[1]: https://man.openbsd.org/pledge

Re: OpenBSD – pinning all system calls

#30
post #17

Earlier quoted context omitted.

Would you mind sharing how and where in the code, specifically. Geniunely curious.

I don't know how they define `MAX`, but I'm guessing it's a typical "a>b?a:b". In function `elf_read_pintable` the `npins` is defined as signed int and `sysno` as unsigned int. So this comparison will be unsigned and will allow to set `npins` to any value, even negative: npins = MAX(npins, syscalls[i].sysno) Then `SYS_kbind` seems to be a signed int. So this comparison will be signed and "fix" the negative `npins` to…

> I don't know how they define `MAX`, but I'm guessing it's a typical "a>b?a:b"

Indeed: https://github.com/openbsd/src/blob/master/sys/sys/param.h#L...

> Then `SYS_kbind` seems to be a signed int.

It's an untyped #define: https://github.com/openbsd/src/blob/master/sys/sys/syscall.h...

I believe your whole analysis is correct, that running an elf file with an openbsd.syscalls entry with .sysno > INT_MAX will allow an out-of-bounds write.

Post reply on HN