Skip to content

pam-tmpdir-helper breaks certain initramfs-update actions on systems with noexec on the /tmp mount #198

@wryMitts

Description

@wryMitts

The Bug

Initramfs related bootscripts may not add all dependencies needed for a system to boot when it's build directory has the noexec flag.

On Kicksecure systems still running initramfs or systems with initramfs-update installed, the pam-tmpdir-helper option being used for the root user will move the environment's tmp directory into /tmp/user/$UID using the TMPDIR variable.

If the noexec flag is also not set for /tmp, this violates assumptions in mkinitramfs related scripts, and may prevent boot, per mkinitramfs (9)

The given directory should be on a filesystem which allows the execution of files stored there, i.e. should not be mounted with the noexec mount option.

Environments Impacted

Environments using keyscripts to unlock LUKS volumes at bootup may be impacted.

The decrypt_keyctl keyscript, a default keyscript available in cryptsetup-initramfs, is used to unlock several LUKS volumes at the same time with the same password. When this keyscript is used, the keyscript itself is added to the initramfs by /etc/crypttab related hooks, although not all dependencies are added until the later initramfs build process.

The correct dependencies are then added by another script, which runs during the initramfs build. The cryptkeyctl script checks if the decrypt_keyctl script is present and executable in the temporary build directory that mkinitramfs uses.

update-initramfs:

Calling hook cryptkeyctl
+ PREREQ=cryptroot
+ . /usr/share/initramfs-tools/hook-functions
+ [ ! -x /tmp/user/0/mkinitramfs_LhQz6c/lib/cryptsetup/scripts/decrypt_keyctl ]
+ exit 0

Reproduction Instructions

  1. Ensure /tmp has noexec set.
  2. Ensure that /etc/pam.d/common-session contains session option pam_tmpdir.so per the recent security-misc patch.
  3. In your /etc/crypttab, add this option: keyscript=decrypt_keyctl so it appears as below:
#<target>    <source>    <keyfile>        <options>
sda_crypt   /dev/sda2   main_data_raid   luks,discard,keyscript=decrypt_keyctl
  1. Run update-initramfs
  2. Reboot

You will get errors about missing dependencies to store the key in the kernel keystore using keyctl. The system will fail to boot since it attempts to pass an 0-byte password to cryptsetup.

Control test:

For a control test, follow the same instructions, but ensure that noexec is NOT set for /tmp.
The volume should unlock normally on reboot.

Causes

The default build directory without pam-tmpdir-helper would otherwise be /var/tmp, which would otherwise be executable.

This is activated by /etc/pam.d/common-session, using the session option pam_tmpdir.so line. I believe the dependency on libpam-tmpdir creates this line per commit 8e66a41, and the function that adds this is called via /usr/share/pam-configs/tmpdir in https://packages.debian.org/sid/amd64/libpam-tmpdir/filelist

I am unsure if this issue impacts dracut systems. Dracut seems to use a customizable temporary directory as well, but I have not studied how hook scripts function, or if they even do function.

Fixes?

I will attempt this workaround to exclude the root user:
https://serverfault.com/a/755956
edit: This does not appear to be functioning for session type modules.

Workaround:
Change the script to check if the file exists and contains greater than zero bytes with the -s flag.

if  [ ! -s "$DESTDIR/lib/cryptsetup/scripts/decrypt_keyctl" ]; then
        exit 0
fi

References

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1062756
https://cryptsetup-team.pages.debian.net/cryptsetup/README.keyctl.html
https://manpages.debian.org/bookworm/initramfs-tools-core/mkinitramfs.8.en.html

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions