scripts: Drop most capabilities

Note this PR requires [bubblewrap 0.2.0](https://github.com/projectatomic/bubblewrap/releases/tag/v0.2.0).

Change our bwrap invocations drop truly dangerous capabilities like
`cap_sys_admin` and `cap_sys_module` just like Docker does today. Because of the
popularity of Docker, we can be pretty sure that most RPM scripts should have
adapted to this (although a problematic area here is that traditional librpm
doesn't actually error out if scripts fail).

There are two reasons to do this:

 - We want "offline" updates by default; updates shouldn't affect the
   running system.  If we prepare the new root in the background, a
   %post shouldn't restart a service for example.  We already "handle"
   this by making `systemctl` a symlink to `/bin/true`, but this approach
   also shuts off `%post`s that do e.g. `insmod`.
 - Protection against accidental system damage

Closes: #1099
Approved by: jlebon
This commit is contained in:
Colin Walters 2017-11-09 14:24:15 -05:00 committed by Atomic Bot
parent b21d0ffc95
commit 90f9fe80e4
4 changed files with 43 additions and 6 deletions

View File

@ -49,11 +49,11 @@ required: true
cluster:
hosts:
- name: vmcheck1
distro: centos/7/atomic
distro: centos/7/atomic/smoketested
- name: vmcheck2
distro: centos/7/atomic
distro: centos/7/atomic/smoketested
- name: vmcheck3
distro: centos/7/atomic
distro: centos/7/atomic/smoketested
container:
image: registry.centos.org/centos/centos:7

View File

@ -35,7 +35,8 @@ adduser testuser
export LSAN_OPTIONS=verbosity=1:log_threads=1
BWRAP=/usr/bin/bwrap
if [ "$id" == centos ]; then
BWRAP=/usr/lib64/rpm-ostree/bwrap
fi
# we use smoketested now, which uses a git master-ish version of bwrap
#if [ "$id" == centos ]; then
# BWRAP=/usr/lib64/rpm-ostree/bwrap
#fi
build --enable-installed-tests --enable-gtk-doc --with-bubblewrap=$BWRAP

View File

@ -231,6 +231,35 @@ rpmostree_bwrap_new (int rootfs_fd,
if (!running_in_nspawn ())
rpmostree_bwrap_append_bwrap_argv (ret, "--unshare-net", NULL);
/* Capabilities; this is a subset of the Docker (1.13 at least) default.
* Specifically we strip out in addition to that:
*
* "cap_net_raw" (no use for this in %post, and major source of security vulnerabilities)
* "cap_mknod" (%post should not be making devices, it wouldn't be persistent anyways)
* "cap_audit_write" (we shouldn't be auditing anything from here)
* "cap_net_bind_service" (nothing should be doing IP networking at all)
*
* But crucially we're dropping a lot of other capabilities like
* "cap_sys_admin", "cap_sys_module", etc that Docker also drops by default.
* We don't want RPM scripts to be doing any of that. Instead, do it from
* systemd unit files.
*
* Also this way we drop out any new capabilities that appear.
*/
if (getuid () == 0)
rpmostree_bwrap_append_bwrap_argv (ret, "--cap-drop", "ALL",
"--cap-add", "cap_chown",
"--cap-add", "cap_dac_override",
"--cap-add", "cap_fowner",
"--cap-add", "cap_fsetid",
"--cap-add", "cap_kill",
"--cap-add", "cap_setgid",
"--cap-add", "cap_setuid",
"--cap-add", "cap_setpcap",
"--cap-add", "cap_sys_chroot",
"--cap-add", "cap_setfcap",
NULL);
for (guint i = 0; i < G_N_ELEMENTS (usr_links); i++)
{
const char *subdir = usr_links[i];

View File

@ -188,6 +188,13 @@ vm_cmd test -f /home/testuser/somedata -a -f /etc/fstab -a -f /tmp/sometmpfile -
assert_file_has_content err.txt 'error: sanitycheck: Executing bwrap(/usr/bin/true)'
echo "ok impervious to rm -rf post"
# capabilities
vm_build_rpm test-cap-drop post "capsh --print > /usr/share/rpmostree-capsh.txt"
vm_rpmostree install test-cap-drop
vm_rpmostree ex livefs
vm_cmd cat /usr/share/rpmostree-capsh.txt > caps.txt
assert_not_file_has_content caps.test '^Current: =.*cap_sys_admin'
vm_build_rpm etc-mutate post "truncate -s 0 /etc/selinux/config"
if vm_rpmostree install etc-mutate; then
assert_not_reached "successfully installed etc-mutate?"