[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