diff --git a/programs/pluto/plutomain.c b/programs/pluto/plutomain.c index 953937ec02..4fc67d3b14 100644 --- a/programs/pluto/plutomain.c +++ b/programs/pluto/plutomain.c @@ -1676,32 +1676,56 @@ int main(int argc, char **argv) #ifdef HAVE_LIBCAP_NG /* + * If we don't have the capability to drop capailities, do nothing. + * * Drop capabilities - this generates a false positive valgrind warning * See: http://marc.info/?l=linux-security-module&m=125895232029657 * * We drop these after creating the pluto socket or else we can't * create a socket if the parent dir is non-root (eg openstack) - */ - capng_clear(CAPNG_SELECT_BOTH); - - capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, - CAP_NET_BIND_SERVICE, CAP_NET_ADMIN, CAP_NET_RAW, - CAP_IPC_LOCK, CAP_AUDIT_WRITE, - /* for google authenticator pam */ - CAP_SETGID, CAP_SETUID, - CAP_DAC_READ_SEARCH, - -1); - /* + * * We need to retain some capabilities for our children (updown): * CAP_NET_ADMIN to change routes * (we also need it for some setsockopt() calls in main process) * CAP_NET_RAW for iptables -t mangle * CAP_DAC_READ_SEARCH for pam / google authenticator - * + * CAP_SETGID, CAP_SETUID for pam / google authenticator */ - capng_updatev(CAPNG_ADD, CAPNG_BOUNDING_SET, CAP_NET_ADMIN, CAP_NET_RAW, - CAP_DAC_READ_SEARCH, -1); - capng_apply(CAPNG_SELECT_BOTH); + if (capng_get_caps_process() == -1) { + llog(RC_LOG_SERIOUS, logger, "failed to query pluto process for capng capabilities"); + } else { + /* If we don't have CAP_SETPCAP, we cannot update the bounding set */ + capng_select_t set = CAPNG_SELECT_CAPS; + if (capng_have_capability (CAPNG_EFFECTIVE, CAP_SETPCAP)) { + set = CAPNG_SELECT_BOTH; + } + + capng_clear(CAPNG_SELECT_BOTH); + if (capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, + CAP_NET_BIND_SERVICE, CAP_NET_ADMIN, CAP_NET_RAW, + CAP_IPC_LOCK, CAP_AUDIT_WRITE, + CAP_SETGID, CAP_SETUID, + CAP_DAC_READ_SEARCH, + -1) != 0) { + llog(RC_LOG_SERIOUS, logger, + "libcap-ng capng_updatev() failed for CAPNG_EFFECTIVE | CAPNG_PERMITTED"); + } + + if (capng_updatev(CAPNG_ADD, CAPNG_BOUNDING_SET, CAP_NET_ADMIN, + CAP_NET_RAW, CAP_DAC_READ_SEARCH, CAP_SETPCAP, + -1) != 0) { + llog(RC_LOG_SERIOUS, logger, + "libcap-ng capng_updatev() failed for CAPNG_BOUNDING_SET"); + } + + int ret = capng_apply(set); + if (ret != CAPNG_NONE) { + llog(RC_LOG_SERIOUS, logger, + "libcap-ng capng_apply failed to apply changes, err=%d. see: man capng_apply", + ret); + } + } + llog(RC_LOG, logger, "libcap-ng support [enabled]"); #else llog(RC_LOG, logger, "libcap-ng support [disabled]"); diff --git a/testing/pluto/TESTLIST b/testing/pluto/TESTLIST index 75f5fcbdca..7826dc9100 100644 --- a/testing/pluto/TESTLIST +++ b/testing/pluto/TESTLIST @@ -842,7 +842,8 @@ kvmplutotest algo-ikev2-aes-md5-esp-3des-sha1 good # CAP_DAC_OVERRIDE kvmplutotest basic-pluto-06 good - +# libcab-ng test +kvmplutotest capabilities-01 good # # a test case of PSK with aggressive mode diff --git a/testing/pluto/capabilities-01/description.txt b/testing/pluto/capabilities-01/description.txt new file mode 100644 index 0000000000..abc1d6e90e --- /dev/null +++ b/testing/pluto/capabilities-01/description.txt @@ -0,0 +1 @@ +Basic test to see if pluto dropped capabilities diff --git a/testing/pluto/capabilities-01/west.conf b/testing/pluto/capabilities-01/west.conf new file mode 100644 index 0000000000..c7b108eae7 --- /dev/null +++ b/testing/pluto/capabilities-01/west.conf @@ -0,0 +1,19 @@ +# /etc/ipsec.conf - Libreswan IPsec configuration file + +version 2.0 + +config setup + # put the logs in /tmp for the UMLs, so that we can operate + # without syslogd, which seems to break on UMLs + logfile=/tmp/pluto.log + logtime=no + logappend=no + plutodebug=all + dumpdir=/tmp + virtual-private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:!192.0.1.0/24,%v6:!2001:db8:0:1::/64 + +conn westnet-eastnet-ipv4-psk-ikev2 + also=westnet-eastnet-ipv4-psk + +include /testing/baseconfigs/all/etc/ipsec.d/ipsec.conf.common + diff --git a/testing/pluto/capabilities-01/west.console.txt b/testing/pluto/capabilities-01/west.console.txt new file mode 100644 index 0000000000..6f98855ad9 --- /dev/null +++ b/testing/pluto/capabilities-01/west.console.txt @@ -0,0 +1,22 @@ +/testing/guestbin/swan-prep +west # + ipsec start +Redirecting to: [initsystem] +west # + ../../guestbin/wait-until-pluto-started +west # + echo "initdone" +initdone +west # + netcap | grep pluto | sed "s/^.*pluto/pluto/" +pluto udp 500 dac_read_search, setgid, setuid, net_bind_service, net_admin, net_raw, ipc_lock, audit_write + +pluto udp 500 dac_read_search, setgid, setuid, net_bind_service, net_admin, net_raw, ipc_lock, audit_write + +pluto udp 500 dac_read_search, setgid, setuid, net_bind_service, net_admin, net_raw, ipc_lock, audit_write + +pluto udp 4500 dac_read_search, setgid, setuid, net_bind_service, net_admin, net_raw, ipc_lock, audit_write + +pluto udp 4500 dac_read_search, setgid, setuid, net_bind_service, net_admin, net_raw, ipc_lock, audit_write + +pluto udp 4500 dac_read_search, setgid, setuid, net_bind_service, net_admin, net_raw, ipc_lock, audit_write + +west # + echo done +done +west # + diff --git a/testing/pluto/capabilities-01/west.secrets b/testing/pluto/capabilities-01/west.secrets new file mode 100644 index 0000000000..d3ed5698d0 --- /dev/null +++ b/testing/pluto/capabilities-01/west.secrets @@ -0,0 +1 @@ +@west @east : PSK "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" diff --git a/testing/pluto/capabilities-01/westinit.sh b/testing/pluto/capabilities-01/westinit.sh new file mode 100755 index 0000000000..f803fcf070 --- /dev/null +++ b/testing/pluto/capabilities-01/westinit.sh @@ -0,0 +1,4 @@ +/testing/guestbin/swan-prep +ipsec start +../../guestbin/wait-until-pluto-started +echo "initdone" diff --git a/testing/pluto/capabilities-01/westrun.sh b/testing/pluto/capabilities-01/westrun.sh new file mode 100755 index 0000000000..379da39994 --- /dev/null +++ b/testing/pluto/capabilities-01/westrun.sh @@ -0,0 +1,2 @@ +netcap | grep pluto | sed "s/^.*pluto/pluto/" +echo done