0

I am trying to create an init script in Debian Buster kernel v5.7.13 that loads some keys for Linux's IMA subsystem. Following the instructions on this man page for evmctl, I wrote/copied a script at /etc/initramfs-tools/scripts/local-top/ima.sh that looks like the following:

#!/bin/sh

# mount securityfs if not mounted
SECFS=/sys/kernel/security
grep -q  $SECFS /proc/mounts || mount -n -t securityfs securityfs $SECFS

# search for IMA trusted keyring, then for untrusted
ima_id="`awk '/\.ima/ { printf "%d", "0x"$1; }' /proc/keys`"
if [ -z "$ima_id" ]; then
    ima_id=`/bin/keyctl search @u keyring _ima 2>/dev/null`
    if [ -z "$ima_id" ]; then
        ima_id=`keyctl newring _ima @u`
    fi
fi
# import IMA X509 certificate
# evmctl import /etc/keys/x509_ima.der $ima_id
evmctl import /etc/keys/x509_evm.der $ima_id

# search for EVM keyring
evm_id=`keyctl search @u keyring _evm 2>/dev/null`
if [ -z "$evm_id" ]; then
    evm_id=`keyctl newring _evm @u`
fi
# import EVM X509 certificate
evmctl import /etc/keys/x509_evm.der $evm_id

# a) import EVM encrypted key
cat /etc/keys/kmk | keyctl padd user kmk @u
keyctl add encrypted evm-key "load `cat /etc/keys/evm-key`" @u

# enable EVM
echo "1" > /sys/kernel/security/evm

After that, I updated my initramfs image by running update-initramfs -u which ran to completion without error. However, when I try to boot the machine, I get the following errors (screenshotted from my VM).

initramfs errors

Am I missing a step here? How do I make certain files available to my initramfs script? I am able to execute the script fine when the system is fully booted.

Thank you for your help.

peachykeen
  • 4,143
  • 4
  • 30
  • 49

1 Answers1

1

I figured out the solution a while ago, but never got around to answering my own question :)

The issue was that I didn't copy the evmctl or keyctl binaries into the initramfs and that is why it couldn't find them. To load the two binaries, I used the following hook script:

#!/bin/sh
# Includes IMA's necessary components in the initramfs image
# Place in /etc/initramfs-tools/hooks

PREREQ=""
prereqs()
{
    echo "$PREREQ"
}

case $1 in
    prereqs)
        prereqs
        exit 0
        ;;
esac

. /usr/share/initramfs-tools/hook-functions
# Begin real processing below this line

# Copy executables we need to initramfs
copy_exec /usr/bin/keyctl /usr/bin
copy_exec /usr/bin/evmctl /usr/bin

# Copy other files to initramfs
mkdir -p $DESTDIR/etc/keys
cp -a /etc/keys/x509_ima.der $DESTDIR/etc/keys

exit 0

And the following script that gets executed during system boot:

#!/bin/sh
# Load keys for IMA
# Place in /etc/initramfs-tools/scripts/local-top

PREREQ=""
prereqs()
{
    echo "$PREREQ"
}

case $1 in
    prereqs)
        prereqs
        exit 0
        ;;
esac

. /scripts/functions
# Begin real processing below this line
if [ ! -x "/usr/bin/keyctl" ]; then
    panic "keyctl executable not found"
fi

if [ ! -x "/usr/bin/evmctl" ]; then
    panic "evmctl executable not found"
fi

if [ ! -f "/etc/keys/x509_ima.der" ]; then
    panic "IMA x509 certificate not found"
fi

# Mount securityfs if not mounted
SECFS=/sys/kernel/security
grep -q  $SECFS /proc/mounts || mount -n -t securityfs securityfs $SECFS

# Create an IMA untrusted keyring
ima_id=`keyctl newring _ima @u`

# Import IMA x509 Certificate
evmctl import /etc/keys/x509_ima.der $ima_id

exit 0

Then, to generate the initramfs image, I used the mkinitramfs command. A lot of this process is described in the initramfs-tools(8) manual if anyone is visiting this in the future and wants to know how I arrived at this answer and how I crafted my script.

peachykeen
  • 4,143
  • 4
  • 30
  • 49