[GH-ISSUE #4558] --tracelog and --trace override /etc/ld.so.preload inside the sandbox #2705

Closed
opened 2026-05-05 09:22:01 -06:00 by gitea-mirror · 4 comments
Owner

Originally created by @rusty-snake on GitHub (Sep 18, 2021).
Original GitHub issue: https://github.com/netblue30/firejail/issues/4558

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...

Originally created by @rusty-snake on GitHub (Sep 18, 2021). Original GitHub issue: https://github.com/netblue30/firejail/issues/4558 ### Description `--tracelog` and `--trace` override `/etc/ld.so.preload` inside the sandbox. ### Steps to Reproduce ```console $ 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`. ```console $ 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. - [x] I have performed a short search for similar issues (to avoid opening a duplicate). ### Log <details> <summary>Output of <code>firejail --debug /path/to/program</code></summary> <p> ``` 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... ``` </p> </details>
gitea-mirror 2026-05-05 09:22:01 -06:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@topimiettinen commented on GitHub (Sep 19, 2021):

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.

<!-- gh-comment-id:922456243 --> @topimiettinen commented on GitHub (Sep 19, 2021): 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.
Author
Owner

@kmk3 commented on GitHub (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?

<!-- gh-comment-id:922865964 --> @kmk3 commented on GitHub (Sep 20, 2021): @topimiettinen commented [on Sep 19](https://github.com/netblue30/firejail/issues/4558#issuecomment-922456243): > 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: * "Developing Software in a Hostile Environment" - <https://www.openbsd.org/papers/dev-sw-hostile-env.html> 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: * <https://man.openbsd.org/OpenBSD-6.9/malloc.3> I don't know much about it, but it looks like it should be doing "randomization [and] security". Thoughts on it?
Author
Owner

@topimiettinen commented on GitHub (Sep 20, 2021):

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.

<!-- gh-comment-id:923097683 --> @topimiettinen commented on GitHub (Sep 20, 2021): > 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.
Author
Owner

@topimiettinen commented on GitHub (Sep 22, 2021):

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

<!-- gh-comment-id:925009607 --> @topimiettinen commented on GitHub (Sep 22, 2021): Ok, after a few days' work, I came up with [libaslrmalloc](https://github.com/topimiettinen/libaslrmalloc). Now I wish its bugs were magically fixed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/firejail#2705
No description provided.