kld* hardening breaks rc scripts in jailed environments
Created by: marinbernard
Context
The HardenedBSD kernel is built with the PAX_HARDENING
flag, which prevents non-root users to use kldstat(2)
to list loaded kernel modules. This restriction also applies to jailed root users.
The rc framework includes a mechanism to ensure a required kernel module is loaded before a service is started. It is implemented with the special variable required_modules
, which allows a rc script to supply a list of required kernel modules, and have the rc framework load them automatically.
When the required_modules
variable is set, module loading is handled by the load_kld()
function in /etc/rc.subr. This function uses the kldtat(8)
utility, which relies on the kldstat(2)
syscall, to check whether a module needs be loaded.
Issue
Since the kldstat(8)
utility relies on the kldstat(2)
syscall to return a list of loaded kernel modules, it becomes unusable in jailed environments because of PAX_HARDENING
restrictions.
As a consequence, the rc framework is unable to load kernel modules in jailed environments, and any rc script defining the required_modules
variable fails to start. This issue affects the following rc scripts in base:
$ grep -e "^required_modules" /etc/rc.d/*
/etc/rc.d/automount:required_modules="autofs"
/etc/rc.d/automountd:required_modules="autofs"
/etc/rc.d/bluetooth:required_modules="ng_bluetooth ng_hci ng_l2cap ng_btsocket"
/etc/rc.d/ctld:required_modules="ctl"
/etc/rc.d/geli:required_modules="geom_eli:g_eli"
/etc/rc.d/hastd:required_modules="geom_gate:g_gate"
/etc/rc.d/hcsecd:required_modules="ng_btsocket"
/etc/rc.d/hostapd:required_modules="wlan_xauth wlan_wep wlan_tkip wlan_ccmp"
/etc/rc.d/ipfilter:required_modules="ipl:ipfilter"
/etc/rc.d/ipfw:required_modules="ipfw"
/etc/rc.d/ipfw_netflow:required_modules="ipfw ng_netflow ng_ipfw"
/etc/rc.d/ipnat:required_modules="ipl:ipfilter"
/etc/rc.d/ippool:required_modules="ipl:ipfilter"
/etc/rc.d/ipsec:required_modules="ipsec"
/etc/rc.d/iscsictl:required_modules="iscsi"
/etc/rc.d/iscsid:required_modules="iscsi"
/etc/rc.d/mdconfig:required_modules="geom_md:g_md"
/etc/rc.d/mdconfig2:required_modules="geom_md:g_md"
/etc/rc.d/natd:required_modules="ipdivert"
/etc/rc.d/nfsclient:required_modules="nfscl:nfs"
/etc/rc.d/pf:required_modules="pf"
/etc/rc.d/pfsync:required_modules="pf pfsync"
/etc/rc.d/rfcomm_pppd_server:required_modules="ng_btsocket"
/etc/rc.d/sdpd:required_modules="ng_btsocket"
/etc/rc.d/ugidfw:required_modules="mac_bsdextended"
/etc/rc.d/wpa_supplicant:required_modules="wlan_wep wlan_tkip wlan_ccmp"
/etc/rc.d/zfs:required_modules="zfs"
/etc/rc.d/zfsbe:required_modules="zfs"
/etc/rc.d/zvol:required_modules="zfs"
Proposed resolution
The simplest way to handle this would be to make the rc framework ignore kernel module operations when:
- It runs within a jailed environment, and
- It detects an hardened kernel
This would fix this issue while still allowing rc to operate normally in regular (non-jailed or non-hardened) environments.