Bugzilla – Bug 988348
VUL-0: CVE-2018-6556: lxc: enable setuid bit on lxc-user-nic
Last modified: 2020-06-29 06:32:55 UTC
We're in the process of moving the devel project for lxc from Virtualization to Virtualization:containers (https://build.opensuse.org/package/show/Virtualization:containers/lxc). We're aiming at full support for unprivileged containers. Since unprivileged users are not allowed to attach veth devices to network bridges, lxc uses lxc-user-nic for a long time to do this. This is the only purpose of this binary and it is the only suid binary shipping with lxc. We're currently removing the suid bit during install but I'd really like to have this on by default. We're planning on packaging lxd and it will need lxc-user-nic as well.
Sorry, maybe I was unclear: I was just talking about Tumbleweed. Thanks!
I think this is more likely for the security team than me.
that sounds like a bad idea to me.
Is this still an issue for you? lxc_user_nic.c is quite a large program for a setuid binary (~1300 lines). A review will take its time. If you really need it I can schedule it for review, but it will take a while until I have time for it.
I will be looking into this. The binary lxc-user-nic is still shipped in Factory, but without the setuid bit. Even if we can accept the setuid binary we will need a separate group for it for whitelisting. For example we are currently about to add a spice-gtk setuid binary only for members of the kvm group (see bug 1083025). So it will make sense for you to adjust the spec file such that the setuid binary can only be executed by members of that group.
Adding current lxc maintainer to CC.
I found one notable issue while reviewing the code of lxc-user-nic. I reported this to the upstream developers by email as per their security reporting guidelines. It's not super critical but for the moment I'm keeping this bug under embargo until I get a reaction from upstream. This is the relevant part from the email I sent: I came across an issue that should be adressed. In the "delete" case the program runs the following piece of code unconditionally with effective uid 0 (from lxc_user_nic.c): ``` } else if (request == LXC_USERNIC_DELETE) { netns_fd = open(args.pid, O_RDONLY); if (netns_fd < 0) { usernic_error("Could not open \"%s\": %s\n", args.pid, strerror(errno)); exit(EXIT_FAILURE); } } ``` `args.pid` is a user controlled parameter and can be an arbitrary path at the moment. Nothing is done with this file descriptor later on in the program except an attempt at `setns(fd, CLONE_NEWNET)` in `is_privileged_over_netns()`. Still this allows the unprivileged caller of the setuid binary to achieve the following: - it can test for existence of files normally not accessible to the caller (information leak). Example: ``` # this file is existing $ /usr/lib/lxc/lxc-user-nic delete path name /root/.bash_history type bridge nic lxc_user_nic.c: 1017: is_privileged_over_netns: Failed to setns() to network namespace Invalid argument lxc_user_nic.c: 1161: main: Process is not privileged over network namespace # this file is not existing $ /usr/lib/lxc/lxc-user-nic delete path name /root/.zsh_history type bridge nic lxc_user_nic.c: 1130: main: Could not open "/root/.zsh_history": No such file or directory ``` - it allows to trigger code paths in the kernel that are normally not accessible to the caller. This can happen when opening special files like character and block devices or files in /proc or /sys. Opening some of these files can cause lock or alloc operations or even more complex things to happen like when opening /dev/ptmx, which causes the allocation of a new master/slave pseudo terminal. Therefore this can lead to DoS like situations or have further unspecified impact. For fixing this I suggest opening the file supplied in `args.pid` only with the permissions of the real user, since this is already done in `is_privileged_over_netns()` anyway. Another approach would be the normalization of the input path and then only allowing a path of the pattern /proc/<pid>/ns/net.
I am through with the code review. lxc-user-nic is surprisingly large and complex for a setuid program. Some of the complexity is due to the typical difficulties of doing string handling and parsing in the C programming language. The parsing of the config file and the handling of the database make up a large part of the complexity. I especially found the logic around the alloted devices hard to follow. Some parts of the code could also use some refactoring. E.g. there is some redundant code around the privilege dropping logic. Some dead code seems also to be around e.g. the command line parameters lxc_path and lxc_name aren't used (any more?). In `lxc_secure_rename_in_ns()` the target network namespace is joined with effective uid 0, only afterwards the privilege is dropped to attempt interface renaming. I don't know if the setuid process temporarily joining an arbitary network namespace could be an issue. After fixing the finding from comment 8 we can whitelist the setuid binary for an explicit group like 'kvm' as I mentioned in comment 6 before.
This was assigned CVE-2018-6556 by upstream. CRD publication date is set to Monday 6th of August at 16:00 UTC.
Hi, Thanks for adding. The corresponding fixes for this issue are located at https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1783591 Matthias does have access to the bug. He was nice enough to get a Launchpad account. :) Thanks! Christian
Christian has troubles with his bsc# bugzilla account that we can't help with currently. So he setup a new account. Hopefully you have got access now.
(In reply to Matthias Gerstner from comment #8) > I found one notable issue while reviewing the code of lxc-user-nic. I > reported this to the upstream developers by email as per their security > reporting guidelines. It's not super critical but for the moment I'm keeping > this bug under embargo until I get a reaction from upstream. > > This is the relevant part from the email I sent: > > > I came across an issue that should be > adressed. In the "delete" case the program runs the following piece of > code unconditionally with effective uid 0 (from lxc_user_nic.c): > > ``` > } else if (request == LXC_USERNIC_DELETE) { > netns_fd = open(args.pid, O_RDONLY); > if (netns_fd < 0) { > usernic_error("Could not open \"%s\": %s\n", args.pid, > strerror(errno)); > exit(EXIT_FAILURE); > } > } > ``` > > `args.pid` is a user controlled parameter and can be an arbitrary path > at the moment. Nothing is done with this file descriptor later on in the > program except an attempt at `setns(fd, CLONE_NEWNET)` in > `is_privileged_over_netns()`. Still this allows the unprivileged caller > of the setuid binary to achieve the following: > > - it can test for existence of files normally not accessible to the > caller (information leak). Example: > ``` > # this file is existing > $ /usr/lib/lxc/lxc-user-nic delete path name /root/.bash_history type > bridge nic > lxc_user_nic.c: 1017: is_privileged_over_netns: Failed to setns() to > network namespace Invalid argument > lxc_user_nic.c: 1161: main: Process is not privileged over network > namespace > > # this file is not existing > $ /usr/lib/lxc/lxc-user-nic delete path name /root/.zsh_history type > bridge nic > lxc_user_nic.c: 1130: main: Could not open "/root/.zsh_history": No such > file or directory > ``` > > - it allows to trigger code paths in the kernel that are normally not > accessible to the caller. This can happen when opening special files > like character and block devices or files in /proc or /sys. Opening > some of these files can cause lock or alloc operations or even more > complex things to happen like when opening /dev/ptmx, which causes the > allocation of a new master/slave pseudo terminal. Therefore this can > lead to DoS like situations or have further unspecified impact. > > For fixing this I suggest opening the file supplied in `args.pid` only > with the permissions of the real user, since this is already done in > `is_privileged_over_netns()` anyway. Another approach would be the > normalization of the input path and then only allowing a path of the > pattern /proc/<pid>/ns/net. Dropping to a uid != 0 before is not possible since we also need to be able to open the network namespace of a process located in a different user namespace. The kernel will refuse this open if we are not the owner. The solution I chose is a little more complicated. It is outlined in the corresponding Launchpad bug report. The link is shared in a comment further above. Thanks! Christian
(In reply to Matthias Gerstner from comment #12) > Christian has troubles with his bsc# bugzilla account that we can't help with > currently. So he setup a new account. Hopefully you have got access now. Works now. :) Thanks! Christian
For completeness, the Ubuntu Launchpad bug that deals with this CVE is at [1]. It is still private due to the embargo. In attachment 778812 [details] the final patch for CVE-2018-6556 can be found. I will look into getting this into our openSUSE packages. Even though we're not shipping lxc-user-nic with the setuid bit set by default, some users may have set it manually. [1]: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1783591
This is an autogenerated message for OBS integration: This bug (988348) was mentioned in https://build.opensuse.org/request/show/627605 15.0 / lxc
Upstream has published the security report.
Thanks everyone! Pleasure working with you. Keep up the good work. :) Christian
(In reply to christian.brauner@ubuntu.com from comment #19) > Thanks everyone! Pleasure working with you. > Keep up the good work. :) Thank you, too! Now that the security issue is handled we should come back to the initial purpose of this bug. That was to whitelist the setuid bit for lxc-user-nic in our openSUSE lxc package. As I outlined in comment 6 I can do this once the binary is installed accessible for a suitable group. Who does want to take care of this? Official bugowner of lxc is opensuse_buildservice@ojkastl.de right now.
(In reply to Matthias Gerstner from comment #20) > Who does want to take care of this? Official bugowner of lxc is > opensuse_buildservice@ojkastl.de right now. Sure, I can try. What do I need to do? Johannes
(In reply to opensuse_buildservice@ojkastl.de from comment #21) > (In reply to Matthias Gerstner from comment #20) > > > Who does want to take care of this? Official bugowner of lxc is > > opensuse_buildservice@ojkastl.de right now. > > Sure, I can try. What do I need to do? Thank you for jumping in. I'm assigning the bug to you. You need to adjust the spec file to install the lxc-user-nic binary setuid with mode 04750, owned by root:kvm. A similar change was made for spice-gtk in bug 1101420. You can look into OBS submission sr#625041 what they did. Basically it's a Requires for group(kvm) and the adjusted %attr line for lxc-user-nic. Once you make this change in the lxc devel project you will get an rpmlint error in the build. Then I will whitelist the setuid configuration, the failure will go away and you can submit the change to Factory.
This is an autogenerated message for OBS integration: This bug (988348) was mentioned in https://build.opensuse.org/request/show/628596 Factory / permissions
openSUSE-SU-2018:2316-1: An update that fixes one vulnerability is now available. Category: security (moderate) Bug References: 988348 CVE References: CVE-2018-6556 Sources used: openSUSE Leap 15.0 (src): lxc-2.0.9-lp150.2.6.1
This is an autogenerated message for OBS integration: This bug (988348) was mentioned in https://build.opensuse.org/request/show/631726 Factory / permissions
Sorry, I was offline for some weeks. I will try to finish the package, that I had partially prepared, this week. Kind Regards, Johannes
Hi all, a fix has been prepared in SR#635958 https://build.opensuse.org/request/show/635958 This also fixes some warnings regarding permissions. I'll test the packages and will merge the SR later this week (and forward to TW), feel free to have a look. Kind Regards, Johannes
Hi all, update has been tested, submitted and accepted to Tumbleweed: https://build.opensuse.org/request/show/638264 Not sure if this needs to be submitted to Leap 15.0... Kind Regards, Johannes
I cannot set this bug to resolved, as it depends on 1102396 which I have no permissions for... Could someone check, what 1102396 is about and remove the "depends"?
(In reply to Johannes Kastl from comment #28) > update has been tested, submitted and accepted to Tumbleweed: > https://build.opensuse.org/request/show/638264 Thank you for dealing with this. Looks good. > Not sure if this needs to be submitted to Leap 15.0... Not necessarily. I we want to backport then we need to create maintenance incidents for both, Base:System/permissions and lxc which is a bit of a hassle. Leap 15.1 is in the works already so the new approach using the group will be available there. (In reply to Johannes Kastl from comment #29) > I cannot set this bug to resolved, as it depends on 1102396 which I have no > permissions for... > > Could someone check, what 1102396 is about and remove the "depends"? I checked. It is a bug about Christian's broken bugzilla account (see comment 12). Since we worked around this I removed the depends.
I'm closing this bug as fixed, there should be nothing left to do here.
This is an autogenerated message for OBS integration: This bug (988348) was mentioned in https://build.opensuse.org/request/show/689178 Factory / lxc
This is an autogenerated message for OBS integration: This bug (988348) was mentioned in https://build.opensuse.org/request/show/689418 Factory / lxc
This is an autogenerated message for OBS integration: This bug (988348) was mentioned in https://build.opensuse.org/request/show/691269 Factory / lxc
This is an autogenerated message for OBS integration: This bug (988348) was mentioned in https://build.opensuse.org/request/show/692121 Factory / lxc https://build.opensuse.org/request/show/692123 42.3 / lxc
This is an autogenerated message for OBS integration: This bug (988348) was mentioned in https://build.opensuse.org/request/show/692624 42.3 / lxc+lxcfs
This is an autogenerated message for OBS integration: This bug (988348) was mentioned in https://build.opensuse.org/request/show/692672 42.3 / lxc+lxcfs
openSUSE-SU-2019:1227-1: An update that solves two vulnerabilities and has one errata is now available. Category: security (important) Bug References: 1122185,1131762,988348 CVE References: CVE-2018-6556,CVE-2019-5736 Sources used: openSUSE Backports SLE-15 (src): lxc-3.1.0-bp150.5.3.1, lxcfs-3.0.3-bp150.3.3.1
openSUSE-SU-2019:1230-1: An update that fixes one vulnerability is now available. Category: security (moderate) Bug References: 988348 CVE References: CVE-2018-6556 Sources used: openSUSE Backports SLE-15 (src): lxc-2.0.9-bp150.5.6.1
This is an autogenerated message for OBS integration: This bug (988348) was mentioned in https://build.opensuse.org/request/show/696918 42.3 / lxc
This is an autogenerated message for OBS integration: This bug (988348) was mentioned in https://build.opensuse.org/request/show/697214 42.3 / lxc
openSUSE-SU-2019:1275-1: An update that solves two vulnerabilities and has one errata is now available. Category: security (important) Bug References: 1122185,1131762,988348 CVE References: CVE-2018-6556,CVE-2019-5736 Sources used: openSUSE Leap 15.0 (src): lxc-3.1.0-lp150.2.10.1, lxcfs-3.0.3-lp150.2.3.1