Comment 15 for bug 1783591

Revision history for this message
Christian Brauner (cbrauner) wrote : Re: [Bug 1783591] Re: lxc-user-nic allows unprivileged users to open arbitrary files

On Thu, Jul 26, 2018 at 11:52:30PM -0000, Serge Hallyn wrote:
> Hi,
>
> looks good, my only complaint would be that the WARN message in
> fhas_fs_type() doesn't seem clear. I'd offer an alternative but I don't

One way to detect whether we are on a ramfs or not is to stat the fs.
However, when the ramfs is a tmpfs then the kernel will report back
tmpfs. So if you statfs for ramfs and get tmpfs back you still need to
go on and parse mountinfo to find out whether you are on a ramfs or not.
I think we can remove this warning here.

> know what you're trying to say :)
>
> Do you think there's any point in enforcing that the filename be 'net' ?

We can't really. lxc-user-nic is not sending /proc/<pid>/ns/net but
rather sends us /proc/<pid>/fd/<nr> which refers to a network namespace
that was preserved at container startup time. If we wanted to enforce
that the filename is "net" we'd need to start making bind-mounts which
leads to a whole set of other problems.
One thing we could do is to do a readlink() after we've verified that
the O_PATH fd refers to a nsfs. But setns() will be called as
setns(<fd>, CLONE_NEWNET) anyway and thus will fail with EINVAL when the
fd does refers to a non-network namespace nsfd. So there's no benefit.

> (i.e. to avoid playing any sorts of games with a userns) Probably not
> because is_privileged_over_netns() will trip over it in its
> setns(netns_fd, CLONE_NEWNET) in that case, right?

Exactly. See the end of my comment right above. :)
I'll update the patch to remove the WARN(). The rest will stay
the same.

Thanks!
Christian

>
> --
> You received this bug notification because you are a member of Ubuntu
> Container Security team, which is subscribed to the bug report.
> https://bugs.launchpad.net/bugs/1783591
>
> Title:
> lxc-user-nic allows unprivileged users to open arbitrary files
>
> Status in lxc package in Ubuntu:
> Triaged
> Status in lxc source package in Xenial:
> Triaged
> Status in lxc source package in Bionic:
> Triaged
> Status in lxc source package in Cosmic:
> Triaged
>
> Bug description:
> Matthias Gerstner from SUSE reported the following:
>
> ```
> Hello,
>
> following the lxc security reporting guidelines [1] I am reporting a
> finding in the lxc-user-nic setuid binary. I'm encrypting this mail as a
> best practice and because I found valid GPG keys for all of your
> adresses. Please find my public key attached to this mail.
>
> In the context of an openSUSE security audit of the lxc-user-nic setuid
> binary [2] (currently private bug) 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.
>
> [1] https://github.com/lxc/lxc/blob/master/README.md#reporting-security-issues
> [2] https://bugzilla.suse.com/show_bug.cgi?id=988348
>
> Best regards
>
> Matthias
> ```
>
> To manage notifications about this bug go to:
> https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1783591/+subscriptions