Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

--tracelog and --trace override /etc/ld.so.preload inside the sandbox #4558

Closed
1 task done
rusty-snake opened this issue Sep 18, 2021 · 4 comments · Fixed by #4586
Closed
1 task done

--tracelog and --trace override /etc/ld.so.preload inside the sandbox #4558

rusty-snake opened this issue Sep 18, 2021 · 4 comments · Fixed by #4586
Labels
bug Something isn't working

Comments

@rusty-snake
Copy link
Collaborator

Description

--tracelog and --trace override /etc/ld.so.preload inside the sandbox.

Steps to Reproduce

$ cat /etc/ld.so.preload
/usr/lib64/libhardened_malloc.so 
$ firejail --noprofile --tracelog cat /etc/ld.so.preload
[…]
/run/firejail/lib/libtracelog.so

Expected behavior

--tracelog and --trace append to an existing /etc/ld.so.preload.

$ firejail --noprofile --tracelog cat /etc/ld.so.preload
[…]
/usr/lib64/libhardened_malloc.so /run/firejail/lib/libtracelog.so

Actual behavior

--tracelog and --trace override an existing /etc/ld.so.preload.

Additional context

Workaround is to env LD_PRELOAD=… in globals.local.

Environment

  • Fedora Workstation 34
  • Firejail 0.9.67 from 7aec067-dirty

Checklist

OT: We need to split-up between regressions with programs/profiles and bug in firejail itself.

  • I have performed a short search for similar issues (to avoid opening a duplicate).

Log

Output of firejail --debug /path/to/program

Autoselecting /bin/bash as shell
Building quoted command line: 'cat' '/etc/ld.so.preload' 
Command name #cat#
DISPLAY=:0 parsed as 0
Using the local network stack
Parent pid 407949, child pid 407950
Initializing child process
Host network configured
PID namespace installed
Mounting tmpfs on /run/firejail/mnt directory
Creating empty /run/firejail/mnt/seccomp directory
Creating empty /run/firejail/mnt/seccomp/seccomp.protocol file
Creating empty /run/firejail/mnt/seccomp/seccomp.postexec file
Creating empty /run/firejail/mnt/seccomp/seccomp.postexec32 file

** Warning: dropping all Linux capabilities and setting NO_NEW_PRIVS prctl **

Mounting /proc filesystem representing the PID namespace
Basic read-only filesystem:
Mounting read-only /etc
2095 2032 253:1 /etc /etc ro,relatime master:1 - xfs /dev/mapper/fedora_localhost--live-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota
mountid=2095 fsname=/etc dir=/etc fstype=xfs
Mounting noexec /etc
2096 2095 253:1 /etc /etc ro,nosuid,nodev,noexec,relatime master:1 - xfs /dev/mapper/fedora_localhost--live-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota
mountid=2096 fsname=/etc dir=/etc fstype=xfs
Mounting read-only /var
2097 2032 253:1 /var /var ro,relatime master:1 - xfs /dev/mapper/fedora_localhost--live-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota
mountid=2097 fsname=/var dir=/var fstype=xfs
Mounting noexec /var
2098 2097 253:1 /var /var ro,nosuid,nodev,noexec,relatime master:1 - xfs /dev/mapper/fedora_localhost--live-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota
mountid=2098 fsname=/var dir=/var fstype=xfs
Mounting read-only /usr
2099 2032 253:1 /usr /usr ro,relatime master:1 - xfs /dev/mapper/fedora_localhost--live-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota
mountid=2099 fsname=/usr dir=/usr fstype=xfs
Mounting tmpfs on /var/lock
Mounting tmpfs on /var/tmp
Mounting tmpfs on /var/log
Create the new utmp file
Mount the new utmp file
Cleaning /home directory
Relabeling /home as /home (system_u:object_r:home_root_t:s0)
Relabeling /home/rusty-snake as /home/aurora (unconfined_u:object_r:user_home_dir_t:s0)
Cleaning /run/user directory
Relabeling /run/user as /run/user (system_u:object_r:user_tmp_t:s0)
Relabeling /run/user/1000 as /run/user/1000 (system_u:object_r:user_tmp_t:s0)
Sanitizing /etc/passwd, UID_MIN 1000
Sanitizing /etc/group, GID_MIN 1000
Disable /home/rusty-snake/.config/firejail
Disable /run/firejail/network
Disable /run/firejail/bandwidth
Disable /run/firejail/name
Disable /run/firejail/profile
Disable /run/firejail/x11
blacklist /run/firejail/dbus
Mounting read-only /proc/sys
Remounting /sys directory
Disable /sys/firmware
Disable /sys/hypervisor
Disable /sys/power
Disable /sys/kernel/debug
Disable /sys/kernel/vmcoreinfo
Disable /proc/sys/fs/binfmt_misc
Disable /proc/sys/kernel/core_pattern
Disable /proc/sys/kernel/modprobe
Disable /proc/sysrq-trigger
Disable /proc/sys/vm/panic_on_oom
Disable /proc/irq
Disable /proc/bus
Disable /proc/timer_list
Disable /proc/kcore
Disable /proc/kallsyms
Disable /usr/lib/modules (requested /lib/modules)
Disable /usr/lib/debug
Disable /boot
Disable /dev/port
Disable /run/user/1000/gnupg
Disable /run/user/1000/systemd
Disable /dev/kmsg
Disable /proc/kmsg
Disable /sys/fs
Disable /sys/module
rebuilding /etc directory
Relabeling /run/firejail/mnt/dns-etc as /etc (system_u:object_r:etc_t:s0)
Creating empty /run/firejail/mnt/dns-etc/resolv.conf file
[…]
Creating empty /run/firejail/mnt/dns-etc/flexiblas64rc file
Mount-bind /run/firejail/mnt/dns-etc on top of /etc
Current directory: /home/aurora/GIT/firejail
Mounting read-only /run/firejail/mnt/seccomp
3404 2092 0:113 /seccomp /run/firejail/mnt/seccomp ro,nosuid - tmpfs tmpfs rw,seclabel,mode=755,inode64
mountid=3404 fsname=/seccomp dir=/run/firejail/mnt/seccomp fstype=tmpfs
Seccomp directory:
ls /run/firejail/mnt/seccomp
drwxr-xr-x root     root             120 .
drwxr-xr-x root     root             200 ..
-rw-r--r-- aurora   aurora           568 seccomp
-rw-r--r-- aurora   aurora           432 seccomp.32
-rw-r--r-- aurora   aurora             0 seccomp.postexec
-rw-r--r-- aurora   aurora             0 seccomp.postexec32
No active seccomp files
Create the new ld.so.preload file
Blacklist violations are logged to syslog
Mount the new ld.so.preload file
Dropping all capabilities
NO_NEW_PRIVS set
Drop privileges: pid 1, uid 1000, gid 1000, nogroups 1
No supplementary groups
Starting application
LD_PRELOAD=(null)
Running 'cat' '/etc/ld.so.preload'  command through /bin/bash
execvp argument 0: /bin/bash
execvp argument 1: -c
execvp argument 2: 'cat' '/etc/ld.so.preload' 
Child process initialized in 32.15 ms
/run/firejail/lib/libtracelog.so
monitoring pid 2

Sandbox monitor: waitpid 2 retval 2 status 0

Parent is shutting down, bye...

@rusty-snake rusty-snake added the bug Something isn't working label Sep 18, 2021
@topimiettinen
Copy link
Collaborator

Off topic, but I wish there was a malloc() library which would not make any compromises on randomization or security. For example, libhardened_malloc uses slab structures to keep allocations together to reduce memory waste. I don't care about memory waste with 16GB of memory which is almost entirely unused! I want the allocator always get a new page at fully random address when the old one is full and realloc() to always move the memory to a new fully random location. With fully random, I don't mean kernel's keep-pages-together algorithm but using all available address space.

@kmk3
Copy link
Collaborator

kmk3 commented Sep 20, 2021

@topimiettinen commented on Sep 19:

Off topic, but I wish there was a malloc() library which would not make any
compromises on randomization or security. For example, libhardened_malloc
uses slab structures to keep allocations together to reduce memory waste. I
don't care about memory waste with 16GB of memory which is almost entirely
unused! I want the allocator always get a new page at fully random address
when the old one is full and realloc() to always move the memory to a new
fully random location. With fully random, I don't mean kernel's
keep-pages-together algorithm but using all available address space.

This reminds me of the following article:

One of the relevant parts:

The J for junk option is the one I'd like to focus on. When enabled, this
option prefills allocated memory with a non zero pattern and overwrites
freed memory as well. This catches two different classes of bugs.

First, many program fail to completely initialize heap objects. Many malloc
implementations, at least for a while after program startup, will return zero
filled memory for allocations because that's what malloc gets from the
kernel. Much like an uninitialzed stack variable, you'll probably get lucky
until you don't. At some point, malloc will switch to returning previously
used memory, which won't be zero, and the bug manifests. Better to catch it
on the first allocation.

Second, many use after free bugs rely on the memory remaining unchanged for
some time after free. Until the memory is recycled, the program can perhaps
continue using it without consequence. By immediately overwriting the memory,
we can trigger erroneous behavior.

There's no guarantee that the junking memory will flush out a bug. However,
we can hope that the junked memory is sufficiently atypical that it causes
observable deviations.

Man page:

I don't know much about it, but it looks like it should be doing "randomization
[and] security". Thoughts on it?

@topimiettinen
Copy link
Collaborator

I don't know much about it, but it looks like it should be doing "randomization
[and] security". Thoughts on it?

Filling memory with junk before malloc() and immediately after free() is nice and very lightweight compared to gcc/llvm MSAN or valgrind. But that's for finding bugs and not for preventing attacks utilizing weak address space layout randomization (ASLR).

I'd make OpenBSD realloc() instead of trying to not to move the mapping, always move. The randomization feature relies on mmap() returning pages at really random addresses and this probably works well on OpenBSD, but on Linux this is not so true (the base is randomized only once). The cache feature could be even counterproductive to security, at least I'd try to make it as small as possible.

@topimiettinen
Copy link
Collaborator

Ok, after a few days' work, I came up with libaslrmalloc. Now I wish its bugs were magically fixed.

kmk3 added a commit to kmk3/firejail that referenced this issue Jan 26, 2022
Note: They are added in the order that the issues were fixed/closed.

Note2: The issues were found through the following url:

https://github.com/netblue30/firejail/issues?q=is%3Aclosed+label%3Abug+-label%3Asecurity+closed%3A%3E2021-06-29+

The date used is the release date of 0.9.66, so in theory the query
should return every bug closed after that.  Security-related issues are
excluded because they will be added separately.

Note3: All issues other than netblue30#4328 were fixed before 0.9.68rc1.

Relates to netblue30#2758 netblue30#4235 netblue30#4328 netblue30#4387 netblue30#4395 netblue30#4460 netblue30#4467 netblue30#4558 netblue30#4560 netblue30#4586.
@kmk3 kmk3 added this to To do in Release 0.9.68 via automation Jan 27, 2022
@kmk3 kmk3 moved this from To do to To Document (RELNOTES/man) in Release 0.9.68 Jan 27, 2022
@kmk3 kmk3 moved this from To Document (RELNOTES/man) to Done (on RELNOTES) in Release 0.9.68 Jan 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
No open projects
Release 0.9.68
  
Done (on RELNOTES)
Development

Successfully merging a pull request may close this issue.

3 participants