diff --git a/modules.d/02caps/README b/modules.d/02caps/README new file mode 100644 index 00000000..57d2538c --- /dev/null +++ b/modules.d/02caps/README @@ -0,0 +1,33 @@ +This adds the following parameters: +rd.caps=1 + turn the caps module on/off +rd.caps.initdrop=cap_sys_module,cap_sys_rawio + drop the specified comma seperated capabilities +rd.caps.disablemodules=1 + turn off module loading +rd.caps.disablekexec=1 + turn off the kexec functionality + +If module loading is turned off, all modules have to be loaded in the +initramfs, which are used later on. This can be done with +"rd.driver.pre=" +rd.driver.pre=autofs4,sunrpc,ipt_REJECT,nf_conntrack_ipv4,.... + +Because the kernel command line would get huge with all those drivers, I +recommend to make use of $initramfs/etc/cmdline. + +So, all rd.caps.* and rd.driver.pre arguments are in caps.conf can be +copied to $initramfs/etc/cmdline with "-i caps.conf /etc/cmdline". + +Also all modules have to be loaded in the initramfs via "--add-drivers". + +The resulting initramfs creation would look like this: + + --add-drivers "autofs4 sunrpc ipt_REJECT nf_conntrack_ipv4 \ + nf_defrag_ipv4 iptable_filter ip_tables + ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack + ip6table_filter ip6_tables dm_mirror dm_region_hash dm_log uinput ppdev + parport_pc parport ipv6 sg 8139too 8139cp mii i2c_piix4 i2c_core ext3 + jbd mbcache sd_mod crc_t10dif sr_mod cdrom ata_generic pata_acpi ata_piix + dm_mod" \ + /boot/initramfs-caps.img diff --git a/modules.d/02caps/caps.sh b/modules.d/02caps/caps.sh new file mode 100755 index 00000000..1732b709 --- /dev/null +++ b/modules.d/02caps/caps.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +capsmode=$(getarg rd.caps) + +if [ "$capsmode" = "1" ]; then + CAPS_INIT_DROP=$(getarg rd.caps.initdrop=) + CAPS_USERMODEHELPER_BSET=$(capsh --drop="$CAPS_INIT_DROP" -- -c 'while read a b ; do [ "$a" = "CapBnd:" ] && echo $((0x${b:$((${#b}-8)):8})) $((0x${b:$((${#b}-16)):8})) && break; done < /proc/self/status') + CAPS_MODULES_DISABLED=$(getarg rd.caps.disablemodules=) + CAPS_KEXEC_DISABLED=$(getarg rd.caps.disablekexec=) + + info "Loading CAPS_MODULES $CAPS_MODULES" + for i in $CAPS_MODULES;do modprobe $i 2>&1 >/dev/null | vinfo; done + + if [ "$CAPS_MODULES_DISABLED" = "1" -a -e /proc/sys/kernel/modules_disabled ]; then + info "Disabling module loading." + echo $CAPS_MODULES_DISABLED > /proc/sys/kernel/modules_disabled + fi + + if [ "$CAPS_KEXEC_DISABLED" = "1" -a -e /proc/sys/kernel/kexec_disabled ]; then + info "Disabling kexec." + echo $CAPS_KEXEC_DISABLED > /proc/sys/kernel/kexec_disabled + fi + + info "CAPS_USERMODEHELPER_BSET=$CAPS_USERMODEHELPER_BSET" + if [ -e /proc/sys/kernel/usermodehelper/bset ]; then + info "Setting usermode helper bounding set." + echo $CAPS_USERMODEHELPER_BSET > /proc/sys/kernel/usermodehelper/bset + echo $CAPS_USERMODEHELPER_BSET > /proc/sys/kernel/usermodehelper/inheritable + fi + + echo "CAPS_INIT_DROP=\"$CAPS_INIT_DROP\"" > /etc/capsdrop + info "Will drop capabilities $CAPS_INIT_DROP from init." +fi + diff --git a/modules.d/02caps/module-setup.sh b/modules.d/02caps/module-setup.sh new file mode 100755 index 00000000..7ad2f25f --- /dev/null +++ b/modules.d/02caps/module-setup.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +check() { + type -P capsh >/dev/null 2>&1 +} + +depends() { + return 0 +} + +install() { + inst_hook pre-pivot 99 "$moddir/caps.sh" + inst $(type -P capsh 2>/dev/null) /usr/sbin/capsh + # capsh wants bash and we need bash also + inst /bin/bash && ln -sf bash "${initdir}/bin/sh" +} + diff --git a/modules.d/99base/init b/modules.d/99base/init index f4da4cce..becc8d4e 100755 --- a/modules.d/99base/init +++ b/modules.d/99base/init @@ -359,8 +359,19 @@ wait_for_loginit export PATH="$OLD_PATH" -exec /sbin/switch_root "$NEWROOT" "$INIT" $initargs || { - echo "Something went very badly wrong in the initramfs. Please " - echo "file a bug against dracut." - emergency_shell -} +if [ -f /etc/capsdrop ]; then + . /etc/capsdrop + info "Calling $INIT with capabilities $CAPS_INIT_DROP dropped." + exec /usr/sbin/capsh --drop="$CAPS_INIT_DROP" -- -c "exec /sbin/switch_root \"$NEWROOT\" \"$INIT\" $initargs" || { + warn "Command:" + warn capsh --drop=$CAPS_INIT_DROP -- -c exec switch_root "$NEWROOT" "$INIT" $initargs + warn "failed." + emergency_shell + } +else + exec /sbin/switch_root "$NEWROOT" "$INIT" $initargs || { + warn "Something went very badly wrong in the initramfs. Please " + warn "file a bug against dracut." + emergency_shell + } +fi