diff options
author | Yogita Urade <yogita.urade@windriver.com> | 2023-08-10 07:00:12 +0000 |
---|---|---|
committer | Steve Sakoman <steve@sakoman.com> | 2023-08-18 03:57:05 -1000 |
commit | ee45db898f26a0e320d49f12f1cdad0861cb7d43 (patch) | |
tree | e6a934bcfd43699fda59a3bb9d69ceea76f4b32b | |
parent | 911a4b03a5ef774610832131e2cb9df0cd33ac78 (diff) | |
download | poky-ee45db898f26a0e320d49f12f1cdad0861cb7d43.tar.gz |
qemu: fix CVE-2023-2861
qemu: 9pfs: prevent opening special files
Reference:
https://nvd.nist.gov/vuln/detail/CVE-2023-2861
(From OE-Core rev: 4dd99f7f48664dbaef7f3a083a9d362552ba44ac)
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r-- | meta/recipes-devtools/qemu/qemu.inc | 1 | ||||
-rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2023-2861.patch | 171 |
2 files changed, 172 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc index 7dc382ffdb..fbfc9f7499 100644 --- a/meta/recipes-devtools/qemu/qemu.inc +++ b/meta/recipes-devtools/qemu/qemu.inc | |||
@@ -39,6 +39,7 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \ | |||
39 | file://CVE-2023-0330.patch \ | 39 | file://CVE-2023-0330.patch \ |
40 | file://CVE-2023-3301.patch \ | 40 | file://CVE-2023-3301.patch \ |
41 | file://CVE-2023-3255.patch \ | 41 | file://CVE-2023-3255.patch \ |
42 | file://CVE-2023-2861.patch \ | ||
42 | " | 43 | " |
43 | UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" | 44 | UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" |
44 | 45 | ||
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2023-2861.patch b/meta/recipes-devtools/qemu/qemu/CVE-2023-2861.patch new file mode 100644 index 0000000000..34be8afe16 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2023-2861.patch | |||
@@ -0,0 +1,171 @@ | |||
1 | From f6b0de53fb87ddefed348a39284c8e2f28dc4eda Mon Sep 17 00:00:00 2001 | ||
2 | From: Christian Schoenebeck <qemu_oss@crudebyte.com> | ||
3 | Date: Wed, 2 Aug 2023 13:02:55 +0000 | ||
4 | Subject: [PATCH] 9pfs: prevent opening special files (CVE-2023-2861) | ||
5 | |||
6 | The 9p protocol does not specifically define how server shall behave when | ||
7 | client tries to open a special file, however from security POV it does | ||
8 | make sense for 9p server to prohibit opening any special file on host side | ||
9 | in general. A sane Linux 9p client for instance would never attempt to | ||
10 | open a special file on host side, it would always handle those exclusively | ||
11 | on its guest side. A malicious client however could potentially escape | ||
12 | from the exported 9p tree by creating and opening a device file on host | ||
13 | side. | ||
14 | |||
15 | With QEMU this could only be exploited in the following unsafe setups: | ||
16 | |||
17 | - Running QEMU binary as root AND 9p 'local' fs driver AND 'passthrough' | ||
18 | security model. | ||
19 | |||
20 | or | ||
21 | |||
22 | - Using 9p 'proxy' fs driver (which is running its helper daemon as | ||
23 | root). | ||
24 | |||
25 | These setups were already discouraged for safety reasons before, | ||
26 | however for obvious reasons we are now tightening behaviour on this. | ||
27 | |||
28 | Fixes: CVE-2023-2861 | ||
29 | Reported-by: Yanwu Shen <ywsPlz@gmail.com> | ||
30 | Reported-by: Jietao Xiao <shawtao1125@gmail.com> | ||
31 | Reported-by: Jinku Li <jkli@xidian.edu.cn> | ||
32 | Reported-by: Wenbo Shen <shenwenbo@zju.edu.cn> | ||
33 | Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com> | ||
34 | Reviewed-by: Greg Kurz <groug@kaod.org> | ||
35 | Reviewed-by: Michael Tokarev <mjt@tls.msk.ru> | ||
36 | Message-Id: <E1q6w7r-0000Q0-NM@lizzy.crudebyte.com> | ||
37 | |||
38 | CVE: CVE-2023-2861 | ||
39 | |||
40 | Upstream-Status: Backport [https://github.com/qemu/qemu/commit/10fad73a2bf1c76c8aa9d6322755e5f877d83ce5] | ||
41 | |||
42 | Signed-off-by: Yogita Urade <yogita.urade@windriver.com> | ||
43 | --- | ||
44 | fsdev/virtfs-proxy-helper.c | 27 ++++++++++++++++++++++++-- | ||
45 | hw/9pfs/9p-util.h | 38 +++++++++++++++++++++++++++++++++++++ | ||
46 | 2 files changed, 63 insertions(+), 2 deletions(-) | ||
47 | |||
48 | diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c | ||
49 | index 5cafcd770..d9511f429 100644 | ||
50 | --- a/fsdev/virtfs-proxy-helper.c | ||
51 | +++ b/fsdev/virtfs-proxy-helper.c | ||
52 | @@ -26,6 +26,7 @@ | ||
53 | #include "qemu/xattr.h" | ||
54 | #include "9p-iov-marshal.h" | ||
55 | #include "hw/9pfs/9p-proxy.h" | ||
56 | +#include "hw/9pfs/9p-util.h" | ||
57 | #include "fsdev/9p-iov-marshal.h" | ||
58 | |||
59 | #define PROGNAME "virtfs-proxy-helper" | ||
60 | @@ -338,6 +339,28 @@ static void resetugid(int suid, int sgid) | ||
61 | } | ||
62 | } | ||
63 | |||
64 | +/* | ||
65 | + * Open regular file or directory. Attempts to open any special file are | ||
66 | + * rejected. | ||
67 | + * | ||
68 | + * returns file descriptor or -1 on error | ||
69 | + */ | ||
70 | +static int open_regular(const char *pathname, int flags, mode_t mode) | ||
71 | +{ | ||
72 | + int fd; | ||
73 | + | ||
74 | + fd = open(pathname, flags, mode); | ||
75 | + if (fd < 0) { | ||
76 | + return fd; | ||
77 | + } | ||
78 | + | ||
79 | + if (close_if_special_file(fd) < 0) { | ||
80 | + return -1; | ||
81 | + } | ||
82 | + | ||
83 | + return fd; | ||
84 | +} | ||
85 | + | ||
86 | /* | ||
87 | * send response in two parts | ||
88 | * 1) ProxyHeader | ||
89 | @@ -682,7 +705,7 @@ static int do_create(struct iovec *iovec) | ||
90 | if (ret < 0) { | ||
91 | goto unmarshal_err_out; | ||
92 | } | ||
93 | - ret = open(path.data, flags, mode); | ||
94 | + ret = open_regular(path.data, flags, mode); | ||
95 | if (ret < 0) { | ||
96 | ret = -errno; | ||
97 | } | ||
98 | @@ -707,7 +730,7 @@ static int do_open(struct iovec *iovec) | ||
99 | if (ret < 0) { | ||
100 | goto err_out; | ||
101 | } | ||
102 | - ret = open(path.data, flags); | ||
103 | + ret = open_regular(path.data, flags, 0); | ||
104 | if (ret < 0) { | ||
105 | ret = -errno; | ||
106 | } | ||
107 | diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h | ||
108 | index c3526144c..6b44e5f7a 100644 | ||
109 | --- a/hw/9pfs/9p-util.h | ||
110 | +++ b/hw/9pfs/9p-util.h | ||
111 | @@ -13,6 +13,8 @@ | ||
112 | #ifndef QEMU_9P_UTIL_H | ||
113 | #define QEMU_9P_UTIL_H | ||
114 | |||
115 | +#include "qemu/error-report.h" | ||
116 | + | ||
117 | #ifdef O_PATH | ||
118 | #define O_PATH_9P_UTIL O_PATH | ||
119 | #else | ||
120 | @@ -112,6 +114,38 @@ static inline void close_preserve_errno(int fd) | ||
121 | errno = serrno; | ||
122 | } | ||
123 | |||
124 | +/** | ||
125 | + * close_if_special_file() - Close @fd if neither regular file nor directory. | ||
126 | + * | ||
127 | + * @fd: file descriptor of open file | ||
128 | + * Return: 0 on regular file or directory, -1 otherwise | ||
129 | + * | ||
130 | + * CVE-2023-2861: Prohibit opening any special file directly on host | ||
131 | + * (especially device files), as a compromised client could potentially gain | ||
132 | + * access outside exported tree under certain, unsafe setups. We expect | ||
133 | + * client to handle I/O on special files exclusively on guest side. | ||
134 | + */ | ||
135 | +static inline int close_if_special_file(int fd) | ||
136 | +{ | ||
137 | + struct stat stbuf; | ||
138 | + | ||
139 | + if (fstat(fd, &stbuf) < 0) { | ||
140 | + close_preserve_errno(fd); | ||
141 | + return -1; | ||
142 | + } | ||
143 | + if (!S_ISREG(stbuf.st_mode) && !S_ISDIR(stbuf.st_mode)) { | ||
144 | + error_report_once( | ||
145 | + "9p: broken or compromised client detected; attempt to open " | ||
146 | + "special file (i.e. neither regular file, nor directory)" | ||
147 | + ); | ||
148 | + close(fd); | ||
149 | + errno = ENXIO; | ||
150 | + return -1; | ||
151 | + } | ||
152 | + | ||
153 | + return 0; | ||
154 | +} | ||
155 | + | ||
156 | static inline int openat_dir(int dirfd, const char *name) | ||
157 | { | ||
158 | return openat(dirfd, name, | ||
159 | @@ -146,6 +180,10 @@ again: | ||
160 | return -1; | ||
161 | } | ||
162 | |||
163 | + if (close_if_special_file(fd) < 0) { | ||
164 | + return -1; | ||
165 | + } | ||
166 | + | ||
167 | serrno = errno; | ||
168 | /* O_NONBLOCK was only needed to open the file. Let's drop it. We don't | ||
169 | * do that with O_PATH since fcntl(F_SETFL) isn't supported, and openat() | ||
170 | -- | ||
171 | 2.40.0 | ||