[lxc-users] Fwd: Security consequences of lxc.id_map not mapping a specific uid and gid
Christian Brauner
christianvanbrauner at gmail.com
Fri Dec 12 12:43:13 UTC 2014
> Quoting Christian Brauner (christianvanbrauner at gmail.com):
> > Hello,
> >
> > I run unprivileged containers and I want them to have access to video and
> > sound devices. Hence, I the following in my ~/.config/lxc/default.conf as
> > suggested on Stéphane's blog:
> >
> > # Container specific configuration
> > lxc.id_map = u 1001 101001 64535
> > lxc.id_map = g 1001 101001 64535
> > # uid and gid 1000 isn’t translated so that the container can access the
> > # X socket and dri and snd and video0 devices
> > lxc.id_map = u 0 100000 1000
> > lxc.id_map = g 0 100000 1000
> > lxc.id_map = u 1000 1000 1
> > lxc.id_map = g 1000 1000 1
> >
> > I was wondering compared to an unprivileged container where I simply
> > map:
> >
> > lxc.id_map=u 0 100000 65536
> > lxc.id_map=g 0 100000 65536
> >
> > 1) Am I significantly more vulnerable when I preserve the uid/gid of my
> > unprivileged user on the host for my user in the container?
>
> That depends on the threats you worry about, I guess. Short answer is
> yes. So if you run a browser as that user in the container, and the
> browser succumbs to say a malicous flash binary, the binary has the
> rights to further proceed on the system with your uid.
>
> I do believe it's worthwhile, still. First, there's a huge difference
> in what it can do as a next step if it's your uid, versus if it is running
> as the host's root uid. Secondly, it will at this point still be confined
> by apparmor and namespacing. Now if you next bind-mount your host user's
> homedir into the container, then you should be ready to kiss anything in
> your homedir goodbye. But if you don't do that, then the fact that the
> exploit is running as your uid shouldn't be all *that* bad. Probably
> the easiest next step for it would be to exploit ownership of the X dir,
> i.e. to snoop your keyboard.
>
> > 2) And is there a different solution which would allow me to grant
> > access to the sound and video devices in /dev/snd and /dev/dri to the
> > user in my unprivileged container while still preserving the standard
> > mapping:
> >
> > lxc.id_map=u 0 100000 65536
> > lxc.id_map=g 0 100000 65536
>
> You could forward sound devices using pulseaudio over the network
> instead. Similarly you could forward X session to 10.0.3.1:0, but
> that will get you slower video.
>
I actually found a nicer solution. I use setfacl to set permissions on
specific devices to specific user. Let's say I wanted my container user
which I assigned uid 1000 in the container (i.e. 101000 as seen from the
host) to access the Xsocket, sound, video and framebuffer devices. Then
I would do:
setfacl -R -m "u:101000:r" /tmp/.X11-unix/X0
setfacl -R -m "u:101000:rw" /dev/snd/*
setfacl -R -m "u:101000:rw" /dev/dri/*
setfacl -R -m "u:101000:rw" /dev/video0
setfacl -R -m "u:101000:rw" /dev/fb0
This way the container user can only access exactly those files/devices
I make available and not everything that my local user on the host has
access to.
> > 3) During container bootup of e.g. Debian Wheezy/Stable is constantly
> > complaining in the following manner (log output below) and I would like to
> > now if this can be avoided:
> >
> >
> >
> > INIT: version 2.88 booting
> > Using makefile-style concurrent boot in runlevel S.
> > Cleaning up temporary files... /tmp.
> > mount: permission denied
> > mount: permission denied
> > mount: permission denied
> > mount: permission denied
> > mount: permission denied
> > Mount point '/dev/console' does not exist. Skipping mount. ... (warning).
> > Mount point '/dev/full' does not exist. Skipping mount. ... (warning).
> > Mount point '/dev/null' does not exist. Skipping mount. ... (warning).
>
> Hm, that's interesting. The /dev/full (etc) bind mount entries should
> end in ",create=file" which should prevent this.
>
> Could you show the container configuration file (and any files which are
> lxc.included, recursively)?
>
Yes, of course:
1) config:
# Template used to create this container:
# /usr/share/lxc/templates/lxc-download
# Parameters passed to the template: -d debian -r wheezy -a amd64
# For additional config options, please look at
# lxc.container.conf(5)
# Distribution configuration
lxc.include = /usr/share/lxc/config/debian.common.conf
lxc.include = /usr/share/lxc/config/debian.userns.conf
lxc.arch = x86_64
# Container specific configuration
lxc.id_map = u 0 100000 65536
lxc.id_map = g 0 100000 65536
lxc.rootfs = /home/chb/.local/share/lxc/stable/rootfs
lxc.utsname = stable
# Network configuration
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.name = eth0
lxc.network.hwaddr = 00:16:3e:3a:f1:12
lxc.network.mtu = 1500
lxc.network.ipv4.gateway = 192.168.200.1
lxc.network.ipv4 = 192.168.200.12/24
# Bind mounts
lxc.mount.entry=/tmp/.X11-unix tmp/.X11-unix none ro,bind,optional,create=dir
lxc.mount.entry=/dev/snd dev/snd none bind,optional,create=dir
lxc.mount.entry=/dev/dri dev/dri none bind,optional,create=dir
lxc.mount.entry=/dev/video0 dev/video0 none bind,optional,create=file
lxc.mount.entry=/dev/fb0 dev/fb0 none bind,optional,create=file
2) /usr/share/lxc/config/debian.common.conf:
# Default pivot location
lxc.pivotdir = lxc_putold
# Default mount entries
lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0
lxc.mount.entry = sysfs sys sysfs defaults 0 0
lxc.mount.entry = /sys/fs/fuse/connections sys/fs/fuse/connections none
bind,optional 0 0
# Default console settings
lxc.tty = 4
lxc.pts = 1024
# Default capabilities
lxc.cap.drop = sys_module mac_admin mac_override sys_time
# When using LXC with apparmor, the container will be confined by
# default.
# If you wish for it to instead run unconfined, copy the following line
# (uncommented) to the container's configuration file.
#lxc.aa_profile = unconfined
# To support container nesting on an Ubuntu host while retaining most of
# apparmor's added security, use the following two lines instead.
#lxc.aa_profile = lxc-container-default-with-nesting
#lxc.hook.mount = /usr/share/lxc/hooks/mountcgroups
# If you wish to allow mounting block filesystems, then use the
# following
# line instead, and make sure to grant access to the block device and/or
# loop
# devices below in lxc.cgroup.devices.allow.
#lxc.aa_profile = lxc-container-default-with-mounting
# Default cgroup limits
lxc.cgroup.devices.deny = a
## Allow any mknod (but not using the node)
lxc.cgroup.devices.allow = c *:* m
lxc.cgroup.devices.allow = b *:* m
## /dev/null and zero
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
## consoles
lxc.cgroup.devices.allow = c 5:0 rwm
lxc.cgroup.devices.allow = c 5:1 rwm
## /dev/{,u}random
lxc.cgroup.devices.allow = c 1:8 rwm
lxc.cgroup.devices.allow = c 1:9 rwm
## /dev/pts/*
lxc.cgroup.devices.allow = c 5:2 rwm
lxc.cgroup.devices.allow = c 136:* rwm
## rtc
lxc.cgroup.devices.allow = c 254:0 rm
## fuse
lxc.cgroup.devices.allow = c 10:229 rwm
## tun
lxc.cgroup.devices.allow = c 10:200 rwm
## full
lxc.cgroup.devices.allow = c 1:7 rwm
## hpet
lxc.cgroup.devices.allow = c 10:228 rwm
## kvm
lxc.cgroup.devices.allow = c 10:232 rwm
## To use loop devices, copy the following line to the container's
## configuration file (uncommented).
#lxc.cgroup.devices.allow = b 7:* rwm
# Blacklist some syscalls which are not safe in privileged
# containers
lxc.seccomp = /usr/share/lxc/config/common.seccomp
3) /user/share/lxc/config/debian.userns.conf:
# CAP_SYS_ADMIN in init-user-ns is required for cgroup.devices
lxc.cgroup.devices.deny =
lxc.cgroup.devices.allow =
# Extra bind-mounts for userns
lxc.mount.entry = /dev/console dev/console none bind,create=file 0 0
lxc.mount.entry = /dev/full dev/full none bind,create=file 0 0
lxc.mount.entry = /dev/null dev/null none bind,create=file 0 0
lxc.mount.entry = /dev/random dev/random none bind,create=file 0 0
lxc.mount.entry = /dev/tty dev/tty none bind,create=file 0 0
lxc.mount.entry = /dev/urandom dev/urandom none bind,create=file 0 0
lxc.mount.entry = /dev/zero dev/zero none bind,create=file 0 0
# Default seccomp policy is not needed for unprivileged containers, and
# non-root users cannot use seccmp without NNP anyway.
lxc.seccomp =
Last but not least:
I got rid of the alsa amixer and chown X socket warnings by disabling
the scripts "alsa-utils" and "x11-common" in /etc/init.d/ on Debian
Squeeze via update-rc.d / insserv.
Christian
> > Mount point '/dev/random' does not exist. Skipping mount. ... (warning).
> > Mount point '/dev/tty' does not exist. Skipping mount. ... (warning).
> > Mount point '/dev/urandom' does not exist. Skipping mount. ... (warning).
> > Mount point '/dev/zero' does not exist. Skipping mount. ... (warning).
> > Mount point '/dev/video0' does not exist. Skipping mount. ... (warning).
> > Mount point '/dev/fb0' does not exist. Skipping mount. ... (warning).
> > Mount point '/dev/console' does not exist. Skipping mount. ... (warning).
> > Mount point '/dev/tty1' does not exist. Skipping mount. ... (warning).
> > Mount point '/dev/tty2' does not exist. Skipping mount. ... (warning).
> > Mount point '/dev/tty3' does not exist. Skipping mount. ... (warning).
> > Mount point '/dev/tty4' does not exist. Skipping mount. ... (warning).
> > udev requires hotplug support, not started ... failed!
> > failed!
> > Activating lvm and md swap...done.
> > Checking file systems...fsck from util-linux 2.20.1
> > done.
> > Mounting local filesystems...done.
> > /etc/init.d/mountall.sh: 59: kill: Illegal number: 4 1
> > Activating swapfile swap...done.
> > Cleaning up temporary files....
> > Setting kernel variables ...done.
> > Configuring network interfaces...done.
> > Cleaning up temporary files....
> > Setting up ALSA...Invalid card number.
> > Usage: amixer <options> [command]
> > Available options:
> > -h,--help this help
> > -c,--card N select the card
> > -D,--device N select the device, default 'default'
> > -d,--debug debug mode
> > -n,--nocheck do not perform range checking
> > -v,--version print version of this program
> > -q,--quiet be quiet
> > -i,--inactive show also inactive controls
> > -a,--abstract L select abstraction level (none or basic)
> > -s,--stdin Read and execute commands from stdin sequentially
> > Available commands:
> > scontrols show all mixer simple controls
> > scontents show contents of all mixer simple controls (default command)
> > sset sID P set contents for one mixer simple control
> > sget sID get contents for one mixer simple control
> > controls show all controls for given card
> > contents show contents of all controls for given card
> > cset cID P set control contents for one control
> > cget cID get control contents for one control
> >
> >
> > Best,
> > Christian
> >
> > System Information:
> >
> > Arch Linux with user namespace supported kernel.
> > lxc 1.0.7
> >
> > this script:
> >
> > cgroups are created with printf '\n\033[42mCreating cgroup
> > hierarchy\033[m\n\n' &&
> > for d in /sys/fs/cgroup/*; do
> > f=$(basename $d)
> > echo "looking at $f"
> > if [ "$f" = "cpuset" ]; then
> > echo 1 | sudo tee -a $d/cgroup.clone_children;
> > elif [ "$f" = "memory" ]; then
> > echo 1 | sudo tee -a $d/memory.use_hierarchy;
> > fi
> > sudo mkdir -p $d/$USER
> > sudo chown -R $USER $d/$USER
> > # add current process to cgroup
> > echo $$ > $d/$USER/tasks
> > done
>
> > _______________________________________________
> > lxc-users mailing list
> > lxc-users at lists.linuxcontainers.org
> > http://lists.linuxcontainers.org/listinfo/lxc-users
>
>
> _______________________________________________
> lxc-users mailing list
> lxc-users at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-users
More information about the lxc-users
mailing list