netblue30 / firejail

Linux namespaces and seccomp-bpf sandbox
https://firejail.wordpress.com
GNU General Public License v2.0
5.83k stars 568 forks source link

memory protection system call "mseal" is now in kernel 6.10 #6355

Closed osevan closed 6 months ago

osevan commented 6 months ago

I hope someone of devs read this and improve firejail sandboxing further with this function.

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0b32d436c015d5a88b3368405e3d8fe82f195a54

Lots of Apps could benefit when inside profile we could make changeable.

Thanks and

Best Regards

"Modern CPUs support memory permissions such as RW and NX bits. The memory permission feature improves security stance on memory corruption bugs, i.e. the attacker can’t just write to arbitrary memory and point the code to it, the memory has to be marked with X bit, or else an exception will happen.

Memory sealing additionally protects the mapping itself against modifications. This is useful to mitigate memory corruption issues where a corrupted pointer is passed to a memory management system. For example, such an attacker primitive can break control-flow integrity guarantees since read-only memory that is supposed to be trusted can become writable or .text pages can get remapped. Memory sealing can automatically be applied by the runtime loader to seal .text and .rodata pages and applications can additionally seal security critical data at runtime.

A similar feature already exists in the XNU kernel with the VM_FLAGS_PERMANENT flag and on OpenBSD with the mimmutable syscall."

rusty-snake commented 6 months ago

improve firejail sandboxing

Lots of Apps could benefit when inside profile we could make changeable.

Hi, do you have a clear concept how this should be integrated into firejail? Where and How.? And how it would help? And what to do when started with an older kernel?

Did you actually understood what it is and what it does? Because I do not see how app could benefit from it when it is changeable with profiles. Especially w/o breaking a lot of apps/systems.

Otherwise I suggest to close this.

osevan commented 6 months ago

I apologize, i thought it could help securing apps memory where malloc functions executed.

rusty-snake commented 6 months ago

Even if that would be the case, it would still be better to implement it in libc so all can benefit.

glitsj16 commented 6 months ago

@rusty-snake

... better to implement it in libc so all can benefit

That's exactly what's happening and is explicitly mentioned in the commit linked by @osevan:

[...]
Use cases:
+==========
+- glibc:
+  The dynamic linker, during loading ELF executables, can apply sealing to
+  non-writable memory segments.
[...]
rusty-snake commented 6 months ago

I was talking about usage in malloc family functions. About ld.so I'm aware of. The problem of usage in malloc is that you can not free as I understand.

topimiettinen commented 6 months ago

mseal() could be also useful if we implemented a privilege separated dynamic linker in Firejail with something like ld-so-daemon (PoC/toy stage, stalled). The idea is that a server (for example Firejail) handles all processing of the ELF files, it performs relocations and only passes file descriptors to the client. The client is sandboxed heavily by Firejail so that no shared libraries or the executable itself are available to it. It uses the file descriptors to map the memory segments without processing. The purpose of privilege separation is that in case an attacker gains control of a process, it shouldn't be able to utilize executable content in the file system since there shouldn't be anything executable accessible. The client could use mseal() to make sure that the executable and read-only memory segments can't be easily modified.

But I have to say that it would be simpler for everybody if glibc ld.so started using mseal(). Dynamic loading is tricky, especially when the goal is to be compatible with glibc (for example the GNU IFUNC (mis)feature used by xz-utils attack).

memory-deny-write-execute (implemented with seccomp) has some overlap to mseal(): the process shouldn't be able to make writable memory areas executable. It doesn't cover the cases of making read-only segments writable or unmapping. Likewise, a part of mseal() could probably be implemented with seccomp by the dynamic linker to give some protection even when using old kernels.

kmk3 commented 5 months ago

(Re-closing as "not planned" since nothing was changed in firejail)

And adding "wontfix" based on the replies above.

kmk3 commented 5 months ago

But I have to say that it would be simpler for everybody if glibc ld.so started using mseal(). Dynamic loading is tricky, especially when the goal is to be compatible with glibc (for example the GNU IFUNC (mis)feature used by xz-utils attack).

Makes sense to me; IIRC openbsd did just that with mprotect and argued that most of the work required was indeed in the dynamic linker/loader.

osevan commented 5 months ago

Glibc mseal function

https://lwn.net/Articles/978010/

osevan commented 4 months ago

mseal() could be also useful if we implemented a privilege separated dynamic linker in Firejail with something like ld-so-daemon (PoC/toy stage, stalled). The idea is that a server (for example Firejail) handles all processing of the ELF files, it performs relocations and only passes file descriptors to the client. The client is sandboxed heavily by Firejail so that no shared libraries or the executable itself are available to it. It uses the file descriptors to map the memory segments without processing. The purpose of privilege separation is that in case an attacker gains control of a process, it shouldn't be able to utilize executable content in the file system since there shouldn't be anything executable accessible. The client could use mseal() to make sure that the executable and read-only memory segments can't be easily modified.

But I have to say that it would be simpler for everybody if glibc ld.so started using mseal(). Dynamic loading is tricky, especially when the goal is to be compatible with glibc (for example the GNU IFUNC (mis)feature used by xz-utils attack).

memory-deny-write-execute (implemented with seccomp) has some overlap to mseal(): the process shouldn't be able to make writable memory areas executable. It doesn't cover the cases of making read-only segments writable or unmapping. Likewise, a part of mseal() could probably be implemented with seccomp by the dynamic linker to give some protection even when using old kernels.

Maybe in future we can test this feature?