74 lines
3.1 KiB
Diff
74 lines
3.1 KiB
Diff
From 1b0469530d7a38b8f8990e114b52530d1bf7f3b8 Mon Sep 17 00:00:00 2001
|
|
From: Maher Azzouzi <maherazz04@gmail.com>
|
|
Date: Sun, 25 Dec 2022 13:50:25 +0100
|
|
Subject: [PATCH] Patching an incoming CVE (CVE-2022-47952)
|
|
|
|
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>
|
|
|
|
[Retrieved from:
|
|
https://github.com/lxc/lxc/commit/1b0469530d7a38b8f8990e114b52530d1bf7f3b8]
|
|
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
|
|
---
|
|
src/lxc/cmd/lxc_user_nic.c | 15 ++++++---------
|
|
1 file changed, 6 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/src/lxc/cmd/lxc_user_nic.c b/src/lxc/cmd/lxc_user_nic.c
|
|
index a91e2259d5..69bc6f17d1 100644
|
|
--- a/src/lxc/cmd/lxc_user_nic.c
|
|
+++ b/src/lxc/cmd/lxc_user_nic.c
|
|
@@ -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);
|
|
}
|