dnsmasq: run the jail with only the capabilities it needs

dnsmasq starts as root in a jail without a capabilities file, so it
holds every capability until it drops to the dnsmasq user, and its DHCP
script helper keeps them as root. Name the five it needs, each of which
dnsmasq refuses to start without: CAP_NET_BIND_SERVICE and CAP_NET_RAW
for its sockets, CAP_NET_ADMIN for ARP injection and nftset,
CAP_SETGID and CAP_SETUID to drop to the dnsmasq user.

dnsmasq creates its pid file as root before dropping, which without
CAP_DAC_OVERRIDE fails in a dnsmasq-owned /var/run/dnsmasq. Make the
directory root:dnsmasq with group write, so root creates the file and
the dnsmasq user still removes it on exit.

This needs procd with "jail: do not lock SECBIT_KEEP_CAPS"; ujail
otherwise makes dnsmasq's PR_SET_KEEPCAPS fail.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
pull/26327/head
Daniel Golle 2026-11-01 19:22:40 +00:00
parent 85810d18ca
commit a5e96c837e
3 changed files with 43 additions and 2 deletions

View File

@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=dnsmasq
PKG_UPSTREAM_VERSION:=2.93
PKG_VERSION:=$(subst test,~~test,$(subst rc,~rc,$(PKG_UPSTREAM_VERSION)))
PKG_RELEASE:=9
PKG_RELEASE:=10
PKG_SOURCE:=$(PKG_NAME)-$(PKG_UPSTREAM_VERSION).tar.xz
PKG_SOURCE_URL:=https://thekelleys.org.uk/dnsmasq/
@ -185,6 +185,8 @@ define Package/dnsmasq/install
$(INSTALL_BIN) ./files/dhcp-script.sh $(1)/usr/lib/dnsmasq/dhcp-script.sh
$(INSTALL_DIR) $(1)/usr/share/acl.d
$(INSTALL_DATA) ./files/dnsmasq_acl.json $(1)/usr/share/acl.d/
$(INSTALL_DIR) $(1)/etc/capabilities
$(INSTALL_DATA) ./files/dnsmasq.capabilities $(1)/etc/capabilities/dnsmasq.json
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/50-dnsmasq-migrate-resolv-conf-auto.sh $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/50-dnsmasq-migrate-ipset.sh $(1)/etc/uci-defaults

View File

@ -0,0 +1,37 @@
{
"bounding": [
"CAP_NET_ADMIN",
"CAP_NET_BIND_SERVICE",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID"
],
"effective": [
"CAP_NET_ADMIN",
"CAP_NET_BIND_SERVICE",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID"
],
"ambient": [
"CAP_NET_ADMIN",
"CAP_NET_BIND_SERVICE",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID"
],
"permitted": [
"CAP_NET_ADMIN",
"CAP_NET_BIND_SERVICE",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID"
],
"inheritable": [
"CAP_NET_ADMIN",
"CAP_NET_BIND_SERVICE",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID"
]
}

View File

@ -934,7 +934,8 @@ dnsmasq_start()
mkdir -p "$(dirname "$CONFIGFILE")"
mkdir -p "$HOSTFILE_DIR"
mkdir -p /var/lib/misc
chown dnsmasq:dnsmasq /var/run/dnsmasq
chown root:dnsmasq /var/run/dnsmasq
chmod 0775 /var/run/dnsmasq
echo "# auto-generated config file from /etc/config/dhcp" > "$CONFIGFILE_TMP"
echo "# auto-generated config file from /etc/config/dhcp" > "$HOSTFILE_TMP"
@ -1283,6 +1284,7 @@ dnsmasq_start()
[ -n "$instance_netdev" ] && procd_set_param netdev $instance_netdev
procd_add_jail dnsmasq ubus log
procd_set_param capabilities /etc/capabilities/dnsmasq.json
procd_add_jail_mount $CONFIGFILE $DHCPBOGUSHOSTNAMEFILE $DHCPSCRIPT $DHCPSCRIPT_DEPENDS
procd_add_jail_mount $EXTRA_MOUNT $RFC6761FILE $TRUSTANCHORSFILE
procd_add_jail_mount $dnsmasqconffile $dnsmasqconfdir $resolvdir $user_dhcpscript