News for hackers. Stuff that matters.
Re:OpenBSD may soon gain further memory protections: immutab... by staticassertion on Friday September 02, 2022 @01:05PM (#32693128)
I was just discussing this sort of thing with some colleagues. Because the stack frame for main contains a bunch of other stuff - environment variables, cli args, etc - it makes it unreliable to try to instrument Linux systems and collect that information. A process can change its name, args, env, at any time. That sort of information is really helpful for forensics.

Currently your only option is to pull data directly from kernel structures, which is fine, but most people aren't doing that.

And then of course there's other cool stuff like being able to 'lock' system calls to the system provided libc, which openbsd can do since they already only support their provided libc.

Unfortunately none of this is likely to get to Linux at any point because:

a) I bet some insane userland processes fuck with their stacks

b) Linux doesn't mandate any libc

edit: Seems like there's some "what is this" being asked. Here's my loose understand!

For starters, libc is the interface to the kernel. Very few programs make syscalls directly (except go programs i guess? lol) on Linux, but on openbsd it's just flat out not allowed. OpenBSD doesn't have the "GNU/Linux" dichotomy - it's all one package deal. As such, they get to mandate how userland calls into the kernel.

Of course, you don't have to listen to openbsd today, because you can just... make those system calls directly. Easy. And this is relevant for security because attackers will do something called ROP, which effectively "reuses" bits of your already-executable code to issue system calls (you can google "return to libc" or "ret2libc").

So, first thing's first, have the kernel actually ensure that the sycall is issued from the memory that libc is mapped into. Cool, solved sort of.

But what if the attacker overwrites that libc? Now you've verified that the call is coming from libc but you don't have integrity.

With immutability the kernel will now enforce that system calls come from libc and that the code can't be overwritten.

Of course, this can extend beyond libc, but I'm assuming that's the main point. This would presumably be a general system call that programs can use themselves to do all sorts of fun things.

edit: Can't respond to replies, HN rate limited me :) sorry. Sounds like I need to read up a bit more, this doesn't address the use case I'd had in mind sadly, but still very cool nonetheless.

Re:OpenBSD may soon gain further memory protections: immutab... by eqvinox on Friday September 02, 2022 @01:42PM (#32693582)
> Because the stack frame for main contains a bunch of other stuff - environment variables, cli args, etc - […] > a) I bet some insane userland processes fuck with their stacks

The new OpenBSD `mimmutable()` call, when applied on the stack, does absolutely nothing to prevent writing or reading the stack. It prevents changing the (virtual memory/pagetable) mapping itself, i.e. mapping in something else, removing the mapping, or changing the mapping attributes (primarily RWX).

Even if some userland process requires an executable stack, that would be indicated with ELF flags and set up by the loader - and then frozen in place.

Re:OpenBSD may soon gain further memory protections: immutab... by jart on Friday September 02, 2022 @02:09PM (#32693950)
Well it technically does if you make a new stack with mmap(MAP_STACK) (or simply round down the stack pointer by a page size) and remove the write access to the top of the original stack and mimmutable it.
Re:OpenBSD may soon gain further memory protections: immutab... by eqvinox on Friday September 02, 2022 @02:17PM (#32694057)
Problem is that those "magic variables" are defined by ABI to be directly above main()'s stack frame… if you're throwing that out, you may equally well leave the stack alone and put the magic stuff in some new place :)

…

Actually, now that I think about it, I guess you could try to put the boundary between main() and the magic bits right on a page boundary, and then change attrs on the magic bits?

Re:OpenBSD may soon gain further memory protections: immutab... by jart on Friday September 02, 2022 @02:25PM (#32694151)
You mean _start()'s stack pointer. Libc can secure them and it's fine. It would probably break the ANSI C standard though if you can't modify argv and environ though. So Libc would need to copy them. But that limits the usefulness of the original tooling proposal unless the operating system has something like /proc/pid/maps that tells you the extent of the system provided stack. I don't think OpenBSD has that. Please prove me wrong since if it does, I'd love to know how.
Re:OpenBSD may soon gain further memory protections: immutab... by eqvinox on Friday September 02, 2022 @02:36PM (#32694292)
> You mean _start()'s stack pointer.

Right, yeah.

> It would probably break the ANSI C standard though if you can't modify argv and environ though.

AFAIK it would also break setproctitle(), unless my memory is off that works by just writing over the argv space.

On the plus side, on Linux /proc/<pid>/environ is a snapshot created at the time of execve() and kept by the kernel, nothing other than execve() can change it (don't quote me on this, I'm only 90% sure.)

Re:OpenBSD may soon gain further memory protections: immutab... by jcranmer on Friday September 02, 2022 @04:42PM (#32695493)
> On the plus side, on Linux /proc/<pid>/environ is a snapshot created at the time of execve() and kept by the kernel, nothing other than execve() can change it (don't quote me on this, I'm only 90% sure.)

prctl(PR_SET_MM_ENV_{START,END}) will change the contents of /proc/<pid>/environ.

From what it looks like in Linux's source code, twiddling the bits at the base of the stack will also cause the procfs file to change--it seems to read directly from the process's memory. Ditto for /cmdline and /auxv, it seems.

Re:OpenBSD may soon gain further memory protections: immutab... by eqvinox on Saturday September 03, 2022 @05:38AM (#32700234)
Now I'm sad :(

… but Thanks for removing a misconception of mine!

Re:OpenBSD may soon gain further memory protections: immutab... by staticassertion on Monday September 05, 2022 @03:40PM (#32728438)
Yep, dug into this the other day and POC'd it to prove that (even without prctl, just direct writing) you can overwrite those values and that will be shown in proc.
Re:OpenBSD may soon gain further memory protections: immutab... by 7vUYjPAG2fnx7fd on Friday September 02, 2022 @03:38PM (#32694924)
No setproctitle on Linux. As far as I know you have to overwrite the argv space (and hopefully not also the environment space).
Re:OpenBSD may soon gain further memory protections: immutab... by eqvinox on Saturday September 03, 2022 @05:40AM (#32700242)
Looking at the sibling post to yours, I'm assuming the "better" approach these days is to allocate a new buffer distinct from argv space and use PR_SET_MM_ARG_{START,END} to point the kernel there.
Re:OpenBSD may soon gain further memory protections: immutab... by jart on Friday September 02, 2022 @01:14PM (#32693239)
> Linux doesn't mandate any libc

Neither does OpenBSD. You're misunderstanding how msyscall() works. It's like Highlander. There can be only one.

Re:OpenBSD may soon gain further memory protections: immutab... by staticassertion on Friday September 02, 2022 @01:53PM (#32693704)
Ah, interesting, I'll have to dig into it more :) I've never used OpenBSD so I've just had to watch on the sidelines. Anywhere I can read more about this?
Re:OpenBSD may soon gain further memory protections: immutab... by jart on Friday September 02, 2022 @02:04PM (#32693881)
The msyscall() man page. The Cosmopolitan Libc source code. In the cosmoverse, we produce static executables that run on six operating systems. The only Libc we use is obviously our own. So when our executables get loaded on OpenBSD, we do the same thing OpenBSD Libc does, which is calling msyscall() so that only a privileged subset of the application is able to use SYSCALL. In our static binary world, that's basically any function that uses the `privileged` keyword. It makes things a little dicey if we want to dynamically link OpenBSD Libc since we have to pull out some aggressive hacks like Xed in that case. But overall it's fine.
Re:OpenBSD may soon gain further memory protections: immutab... by 10000truths on Friday September 02, 2022 @06:46PM (#32696559)
> Very few programs make syscalls directly (except go programs i guess? lol) on Linux

You’re forgetting statically compiled binaries, which are very important for ease of deployment and distro-agnostic execution.

Re:OpenBSD may soon gain further memory protections: immutab... by staticassertion on Monday September 05, 2022 @03:38PM (#32728417)
Statically compiled binaries almost always still use a libc, either by dynamically linking it or by statically linking it.
Re:OpenBSD may soon gain further memory protections: immutab... by leni536 on Friday September 02, 2022 @05:29PM (#32695911)
> a) I bet some insane userland processes fuck with their stacks

What do you mean by "insane" here? In standard C you get char** argv, and the arguments live on the stack. I believe you are allowed to modify those cli arguments through the pointers, it is not undefined behavior.

Re:OpenBSD may soon gain further memory protections: immutab... by staticassertion on Monday September 05, 2022 @03:37PM (#32728404)
I never called it undefined behavior. But you shouldn't modify that stack space directly, you should either use setenv via libc or you should use prctl.
Re:OpenBSD may soon gain further memory protections: immutab... by saagarjha on Friday September 02, 2022 @01:53PM (#32693709)
> And this is relevant for security because attackers will do something called ROP, which effectively "reuses" bits of your already-executable code to issue system calls (you can google "return to libc" or "ret2libc").

You’ve just described why system call integrity is useless without strong CFI :)