#3123 PR merged: Make initrd accessible only by root

Labels: fixed / solved / done, critical / security / legal

jsmeix opened issue at 2024-01-08 13:43:

  • Type: Bug Fix

  • Impact: Normal / Critical

Normally (i.e. by default) the ReaR recovery system
does not contain secrets but when it contains secrets
and when GRUB_RESCUE=Y is used then it is critical
that only root is allowed to access the initrd.

In pack/GNU/Linux/900_create_initramfs.sh call
chmod 0600 "$TMP_DIR/$REAR_INITRD_FILENAME"
to let only root access the initrd because
the ReaR recovery system can contain secrets

jsmeix commented at 2024-01-09 09:22:

@schlomo
Wow!
Regardless how long I worked with ReaR there is always
something important that I did not yet notice,
like output/default/010_set_umask.sh
Thank you for pointing that out!

schlomo commented at 2024-01-09 09:23:

No worries @jsmeix, I also didn't know about that. I thought to myself "umask might be a good idea" and simply searched for umask in the code to see if there is something with it already.

jsmeix commented at 2024-01-09 09:28:

Meanwhile I think this current (untested) proposed fix
is highly questionable because it does 'chmod 0600'
for the initrd in ReaR's $TMP_DIR which is not
the final initrd that is located in the
world-readable '/boot/' directory for GRUB_RESCUE=Y.
Perhaps things somehow work via 'cp -p' or similar
but in general I think it would be better (i.e. more fail-safe)
to set the intended permissions for the final initrd file
for GRUB_RESCUE=Y and perhaps also for other methods.

schlomo commented at 2024-01-09 09:55:

Yes, I think ReaR should be careful to not mess up things somewhere else. So for example I see value in protecting the final boot files on the local filesystem, but I wouldn't want to touch stuff on remote filesystems mounted via NFS or CIFS. I'd rather assume that appropriate measures are in place on the other server.

jsmeix commented at 2024-01-09 12:14:

Yes, I also won't care about non-built-in storage
like removable (USB) disks or similar things
i.e. storage where others could get physical access
so that the user who runs "rear mkrescue/mkbackup"
must care on his own how to protect such storage.

Regarding the ReaR ISO on the local filesystem:
With

OUTPUT=ISO
BACKUP=NETFS
BACKUP_URL=file:///other

I get after "rear mkrescue":

# ls -l var/lib/rear/output/rear-linux-h9wr.iso
-rw------- 1 root root 96038912 Jan  9 11:41 var/lib/rear/output/rear-linux-h9wr.iso

# ls -ld var/lib/rear/output
drwxr-xr-x 2 root root 4096 Jan  9 11:41 var/lib/rear/output

# ls -ld var/lib/rear
drwxr-xr-x 6 root root 4096 Jan  9 11:39 var/lib/rear

and (because of BACKUP_URL=file:///other)

# find /other -type f -name '*.iso' -ls
376836 93884 -rw------- 1 root root 96038912 Jan 9 11:41 /other/linux-h9wr/rear-linux-h9wr.iso

I get the same restrictive permissions
when I change output/default/010_set_umask.sh to only

DebugPrint "umask is $( umask )"

which results for me

# usr/sbin/rear -D mkrescue
...
umask is 0022
Making ISO image
Wrote ISO image: /root/rear.github.master/var/lib/rear/output/rear-linux-h9wr.iso (92M)
Copying resulting files to file location
Saving /root/rear.github.master/var/log/rear/rear-linux-h9wr.log as rear-linux-h9wr.log to file location
Copying result files '/root/rear.github.master/var/lib/rear/output/rear-linux-h9wr.iso /var/tmp/rear.Tr8IxEGGpwI5EJ4/tmp/VERSION /var/tmp/rear.Tr8IxEGGpwI5EJ4/tmp/README /var/tmp/rear.Tr8IxEGGpwI5EJ4/tmp/rear-linux-h9wr.log' to /other/linux-h9wr at file location
Exiting rear mkrescue (PID 25518) and its descendant processes ...

Currently I fail to see how and where that restrictive permissions
are set in ReaR for the *.iso files.

jsmeix commented at 2024-01-09 13:55:

Interestingly the current fix
results restrictive permissions for
the final initrd that is located in the
world-readable '/boot/' directory for GRUB_RESCUE=Y.

With

OUTPUT=ISO
BACKUP=NETFS
BACKUP_URL=nfs://192.168.122.1/nfs
GRUB_RESCUE=Y

Without the current fix:

# usr/sbin/rear -D mkrescue
...

# find /boot -name '*initrd*' -ls
...
... -rw-r--r-- 1 root root 68010481 Jan  9 14:41 /boot/rear-initrd.cgz

In contrast with the current fix:

# usr/sbin/rear -D mkrescue
...

# find /boot -name '*initrd*' -ls
...
... -rw------- 1 root root 68001719 Jan  9 14:45 /boot/rear-initrd.cgz

jsmeix commented at 2024-01-09 14:33:

Without this fix here
but with an early umask 0077 in
init/default/001_verify_config_arrays.sh
(there only for now for my test)
and with disabled output/default/010_set_umask.sh
I also get restrictive permissions for
the final initrd that is located in the
world-readable '/boot/' directory for GRUB_RESCUE=Y

# usr/sbin/rear -D mkrescue
...

# find /boot -name '*initrd*' -ls
...
... -rw------- 1 root root 68003492 Jan  9 15:24 /boot/rear-initrd.cgz

Furthermore I also get restrictive permissions
for many ReaR files in var/ in particular

drwxr-xr-x 1 root root var
drwxr-xr-x 1 root root var/log
drwxr-xr-x 1 root root var/log/rear
-rw------- 1 root root var/log/rear/rear-localhost.log
drwx------ 1 root root var/lib
drwx------ 1 root root var/lib/rear
drwxr-xr-x 1 root root var/lib/rear/output
-rw------- 1 root root var/lib/rear/output/rear-localhost.iso
drwx------ 1 root root var/lib/rear/recovery
-rw------- 1 root root var/lib/rear/recovery/bootdisk
-rw------- 1 root root var/lib/rear/recovery/directories_permissions_owner_group
-rw------- 1 root root var/lib/rear/recovery/diskbyid_mappings
-rw------- 1 root root var/lib/rear/recovery/mountpoint_device
-rw------- 1 root root var/lib/rear/recovery/bootloader
-rw------- 1 root root var/lib/rear/recovery/initrd_modules
-rw------- 1 root root var/lib/rear/recovery/storage_drivers
-rw------- 1 root root var/lib/rear/recovery/if_inet6
drwx------ 1 root root var/lib/rear/layout
drwx------ 1 root root var/lib/rear/layout/config
-rw------- 1 root root var/lib/rear/layout/config/df.txt
-rw------- 1 root root var/lib/rear/layout/config/files.md5sum
-rw------- 1 root root var/lib/rear/layout/disklayout.conf
-rw------- 1 root root var/lib/rear/layout/diskdeps.conf
-rw------- 1 root root var/lib/rear/layout/disktodo.conf
drwx------ 1 root root var/lib/rear/layout/lvm
drwxr-xr-x 1 root root var/lib/rear/sysreqs
-rw------- 1 root root var/lib/rear/sysreqs/Minimal_System_Requirements.txt

jsmeix commented at 2024-01-09 14:41:

I understand now why this fix here works for GRUB_RESCUE=Y

In output/default/940_grub2_rescue.sh there is

local initrd_file=$TMP_DIR/$REAR_INITRD_FILENAME
...
local boot_dir="/boot"
...
local boot_initrd_name="rear-$REAR_INITRD_FILENAME"
...
local boot_initrd_file="$boot_dir/$boot_initrd_name"
.
.
.
cp -af $v $initrd_file $boot_initrd_file || BugError "..."

so this fix here works because $TMP_DIR/$REAR_INITRD_FILENAME
is copied via 'cp -a' so in particular permissions are preserved.

pcahyna commented at 2024-01-09 14:57:

Yes, I also won't care about non-built-in storage
like removable (USB) disks or similar things
i.e. storage where others could get physical access
so that the user who runs "rear mkrescue/mkbackup"
must care on his own how to protect such storage.

I would care about this, because someone could access the USB in the time window when it is mounted. Fortunately I believe we mount it under $TMP_DIR, which is not world-accessible, right? But there could be some script that "helpfully" automounts the rescue medium under /media or something.

jsmeix commented at 2024-01-09 15:49:

Regarding "helpfully" automounts the rescue medium:

When I plug in my ReaR USB disk I get automatically
this (on openSUSE Leap 15.5):

# mount | grep sdb
/dev/sdb3 on /run/media/johannes/REAR-000 type ext3 (rw,nosuid,nodev,relatime,errors=remount-ro,uhelper=udisks2)

# ls -l /run/media/johannes/REAR-000
drwx------ 3 root root ... boot
drwxr-x--- 2 root root ... linux-h9wr
drwx------ 2 root root ... lost+found
drwx------ 3 root root ... rear

so no non-root user can access things therein
and because of

# usr/sbin/rear -D mkrescue
...
ERROR: USB or disk device '/dev/sdb3' is already mounted on '/run/media/johannes/REAR-000'

I must unmount that before I can use it for ReaR.

After unmount
with

OUTPUT=USB
BACKUP=NETFS
BACKUP_URL=usb:///dev/disk/by-label/REAR-000

I get

# usr/sbin/rear -D mkbackup
...
Using build area: /var/tmp/rear.VPPdGWHa1qLmwvJ
...
Creating tar archive '/var/tmp/rear.VPPdGWHa1qLmwvJ/outputfs/rear/linux-h9wr/20240109.1634/backup.tar.gz'
...

# ls -ld /var/tmp/rear.VPPdGWHa1qLmwvJ
drwx------ 4 root root 4096 Jan  9 16:35 /var/tmp/rear.VPPdGWHa1qLmwvJ

# grep '+ mount ' var/log/rear/rear-linux-h9wr.log
+++ mount -v -o rw,noatime /dev/disk/by-label/REAR-000 /var/tmp/rear.VPPdGWHa1qLmwvJ/outputfs
+++ mount -v -o rw,noatime /dev/disk/by-label/REAR-000 /var/tmp/rear.VPPdGWHa1qLmwvJ/outputfs
+++ mount -v -o rw,noatime /dev/disk/by-label/REAR-000 /var/tmp/rear.VPPdGWHa1qLmwvJ/outputfs

so as far as I see normally ReaR mounts below $BUILD_DIR
but that depends on how e.g. mount_url() is called
where $2 is the mountpoint
that is I my case

# grep '+ mount_url ' var/log/rear/rear-linux-h9wr.log
++ mount_url usb:///dev/disk/by-label/REAR-000 /var/tmp/rear.VPPdGWHa1qLmwvJ/outputfs
++ mount_url usb:///dev/disk/by-label/REAR-000 /var/tmp/rear.VPPdGWHa1qLmwvJ/outputfs
++ mount_url usb:///dev/disk/by-label/REAR-000 /var/tmp/rear.VPPdGWHa1qLmwvJ/outputfs

but there could be any mountpoint specified and
there could be also any mount command in the ReaR code
and actually there are many mount commands in the ReaR code

jsmeix commented at 2024-01-10 14:21:

@rear/contributors
I would like to merge this PR in its current state
rather soon because it fixes the specific issue
https://github.com/rear/rear/issues/3122

The generic issue that possibly confidential values
may leak out via the ReaR recovery system in ReaR's initrd
will need a lot of time for careful investigation
which must be done via separated issues and pull requests.

jsmeix commented at 2024-01-12 12:02:

Verification for older ReaR versions
(those older ReaR versions which we have in SUSE, cf.
https://en.opensuse.org/SDB:Disaster_Recovery#Relax-and-Recover_(ReaR)_RPM_packages_for_disaster_recovery)
that ReaR's initrd gets copied via 'cp -a'
so its permissions are preserved, cf. my above
https://github.com/rear/rear/pull/3123#issuecomment-1883175016
when ReaR's initrd is copied in case of GRUB_RESCUE=Y
for GRUB Legacy
via output/default/94_grub_rescue.sh
or output/default/940_grub_rescue.sh
and for GRUB 2
via output/default/94_grub2_rescue.sh
or output/default/940_grub2_rescue.sh

rear-1.16/usr/share/rear/output/default/94_grub_rescue.sh
cp -af $v $TMP_DIR/initrd.cgz /boot/rear-initrd.cgz >&2
=======================
rear-1.17.2/usr/share/rear/output/default/94_grub_rescue.sh
cp -af $v $TMP_DIR/initrd.cgz /boot/rear-initrd.cgz >&2
=======================
rear-1.17.2/usr/share/rear/output/default/94_grub2_rescue.sh
cp -af $v $TMP_DIR/initrd.cgz /boot/rear-initrd.cgz >&2
=======================
rear-1.18.a/usr/share/rear/output/default/94_grub_rescue.sh
cp -af $v $TMP_DIR/initrd.cgz /boot/rear-initrd.cgz >&2
=======================
rear-1.18.a/usr/share/rear/output/default/94_grub2_rescue.sh
cp -af $v $initrd_file $boot_initrd_file >&2 || BugError "Unable to copy '$initrd_file' to '$boot_initrd_file'."
=======================
rear-2.3.a/usr/share/rear/output/default/940_grub_rescue.sh
cp -af $v $TMP_DIR/$REAR_INITRD_FILENAME /boot/rear-$REAR_INITRD_FILENAME >&2
=======================
rear-2.3.a/usr/share/rear/output/default/940_grub2_rescue.sh
cp -af $v $initrd_file $boot_initrd_file >&2 || BugError "Unable to copy '$initrd_file' to '$boot_initrd_file'."
=======================
rear-2.7/usr/share/rear/output/default/940_grub_rescue.sh
cp -af $v $TMP_DIR/$REAR_INITRD_FILENAME /boot/rear-$REAR_INITRD_FILENAME || BugError "Failed to copy '$TMP_DIR/$REAR_INITRD_FILENAME' to '/boot/rear-$REAR_INITRD_FILENAME'"
=======================
rear-2.7/usr/share/rear/output/default/940_grub2_rescue.sh
cp -af $v $initrd_file $boot_initrd_file || BugError "Failed to copy '$initrd_file' to '$boot_initrd_file'"

jsmeix commented at 2024-01-15 10:43:

https://bugzilla.opensuse.org/show_bug.cgi?id=1218728
"CVE-2024-23301: rear: GRUB_RESCUE=Y creates world-readable initrd"

jsmeix commented at 2024-01-15 11:03:

Regarding GRUB_RESCUE=Y for GRUB Legacy on SUSE SLES systems:
The SUSE SLES12 release notes
https://www.suse.com/releasenotes/x86_64/SUSE-SLES/12/index.html
read (excerpt):

8.4.8.9 GRUB2 Is the Supported Bootloader
GRUB2 is now available
on all SUSE Linux Enterprise 12 architectures
and is the only supported bootloader.
Other bootloaders that were supported in SLE 11, have been
removed from the distribution and are not available anymore.

[Export of Github issue for rear/rear.]