]> git.proxmox.com Git - mirror_lxc.git/commitdiff
Patching an incoming CVE (CVE-2022-47952)
authorMaher Azzouzi <maherazz04@gmail.com>
Sun, 25 Dec 2022 12:50:25 +0000 (13:50 +0100)
committerSerge Hallyn <serge@hallyn.com>
Fri, 6 Jan 2023 14:47:43 +0000 (08:47 -0600)
lxc-user-nic in lxc through 5.0.1 is installed setuid root, and may
allow local users to infer whether any file exists, even within a
protected directory tree, because "Failed to open" often indicates
that a file does not exist, whereas "does not refer to a network
namespace path" often indicates that a file exists. NOTE: this is
different from CVE-2018-6556 because the CVE-2018-6556 fix design was
based on the premise that "we will report back to the user that the
open() failed but the user has no way of knowing why it failed";
however, in many realistic cases, there are no plausible reasons for
failing except that the file does not exist.

PoC:
> % ls /l
> ls: cannot open directory '/l': Permission denied
> % /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic delete lol lol /l/h/tt h h
> cmd/lxc_user_nic.c: 1096: main: Failed to open "/l/h/tt" <----- file does not exist.
> % /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic delete lol lol /l/h/t h h
> cmd/lxc_user_nic.c: 1101: main: Path "/l/h/t" does not refer to a network namespace path <---- file exist!

Signed-off-by: MaherAzzouzi <maherazz04@gmail.com>
Acked-by: Serge Hallyn <serge@hallyn.com>
src/lxc/cmd/lxc_user_nic.c

index a91e2259d56c4f4eac342314988254c3f6230f55..69bc6f17d12490b8aae495c6b6c6b20cc840f17f 100644 (file)
@@ -1085,20 +1085,17 @@ int main(int argc, char *argv[])
        } else if (request == LXC_USERNIC_DELETE) {
                char opath[LXC_PROC_PID_FD_LEN];
 
-               /* Open the path with O_PATH which will not trigger an actual
-                * open(). Don't report an errno to the caller to not leak
-                * information whether the path exists or not.
-                * When stracing setuid is stripped so this is not a concern
-                * either.
-                */
+               // Keep in mind CVE-2022-47952: It's crucial not to leak any
+               // information whether open() succeeded of failed.
+
                netns_fd = open(args.pid, O_PATH | O_CLOEXEC);
                if (netns_fd < 0) {
-                       usernic_error("Failed to open \"%s\"\n", args.pid);
+                       usernic_error("Failed while opening netns file for \"%s\"\n", args.pid);
                        _exit(EXIT_FAILURE);
                }
 
                if (!fhas_fs_type(netns_fd, NSFS_MAGIC)) {
-                       usernic_error("Path \"%s\" does not refer to a network namespace path\n", args.pid);
+                       usernic_error("Failed while opening netns file for \"%s\"\n", args.pid);
                        close(netns_fd);
                        _exit(EXIT_FAILURE);
                }
@@ -1112,7 +1109,7 @@ int main(int argc, char *argv[])
                /* Now get an fd that we can use in setns() calls. */
                ret = open(opath, O_RDONLY | O_CLOEXEC);
                if (ret < 0) {
-                       CMD_SYSERROR("Failed to open \"%s\"\n", args.pid);
+                       CMD_SYSERROR("Failed while opening netns file for \"%s\"\n", args.pid);
                        close(netns_fd);
                        _exit(EXIT_FAILURE);
                }