mirror of
https://git.yoctoproject.org/poky
synced 2026-04-17 18:32:12 +02:00
qemu: fix CVE-2023-2861
9pfs: prevent opening special files
References:
https://nvd.nist.gov/vuln/detail/CVE-2023-2861
Upstream patches:
10fad73a2b
(From OE-Core rev: 9bd4ddeb4b5efc65b0514d50d6991211271924c1)
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
This commit is contained in:
committed by
Steve Sakoman
parent
76f6267368
commit
ae7992e3b7
@@ -96,6 +96,7 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
|
||||
file://CVE-2023-0330.patch \
|
||||
file://CVE-2023-3301.patch \
|
||||
file://CVE-2023-3255.patch \
|
||||
file://CVE-2023-2861.patch \
|
||||
"
|
||||
UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
|
||||
|
||||
|
||||
172
meta/recipes-devtools/qemu/qemu/CVE-2023-2861.patch
Normal file
172
meta/recipes-devtools/qemu/qemu/CVE-2023-2861.patch
Normal file
@@ -0,0 +1,172 @@
|
||||
From 10fad73a2bf1c76c8aa9d6322755e5f877d83ce5 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Schoenebeck <qemu_oss@crudebyte.com>
|
||||
Date: Wed Jun 7 18:29:33 2023 +0200
|
||||
Subject: [PATCH] 9pfs: prevent opening special files (CVE-2023-2861) The 9p
|
||||
protocol does not specifically define how server shall behave when client
|
||||
tries to open a special file, however from security POV it does make sense
|
||||
for 9p server to prohibit opening any special file on host side in general. A
|
||||
sane Linux 9p client for instance would never attempt to open a special file
|
||||
on host side, it would always handle those exclusively on its guest side. A
|
||||
malicious client however could potentially escape from the exported 9p tree
|
||||
by creating and opening a device file on host side.
|
||||
|
||||
With QEMU this could only be exploited in the following unsafe setups:
|
||||
|
||||
- Running QEMU binary as root AND 9p 'local' fs driver AND 'passthrough'
|
||||
security model.
|
||||
|
||||
or
|
||||
|
||||
- Using 9p 'proxy' fs driver (which is running its helper daemon as
|
||||
root).
|
||||
|
||||
These setups were already discouraged for safety reasons before,
|
||||
however for obvious reasons we are now tightening behaviour on this.
|
||||
|
||||
Fixes: CVE-2023-2861
|
||||
Reported-by: Yanwu Shen <ywsPlz@gmail.com>
|
||||
Reported-by: Jietao Xiao <shawtao1125@gmail.com>
|
||||
Reported-by: Jinku Li <jkli@xidian.edu.cn>
|
||||
Reported-by: Wenbo Shen <shenwenbo@zju.edu.cn>
|
||||
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
|
||||
Reviewed-by: Greg Kurz <groug@kaod.org>
|
||||
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
|
||||
Message-Id: <E1q6w7r-0000Q0-NM@lizzy.crudebyte.com>
|
||||
(cherry picked from commit f6b0de5)
|
||||
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
|
||||
(Mjt: drop adding qemu_fstat wrapper for 7.2 where wrappers aren't used)
|
||||
|
||||
Upstream-Status: Backport [https://github.com/qemu/qemu/commit/10fad73a2bf1c76c8aa9d6322755e5f877d83ce5]
|
||||
|
||||
CVE: CVE-2023-2861
|
||||
|
||||
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||
---
|
||||
fsdev/virtfs-proxy-helper.c | 27 ++++++++++++++++++++++++--
|
||||
hw/9pfs/9p-util.h | 38 +++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 63 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
|
||||
index 15c0e79b0..f9e4669a5 100644
|
||||
--- a/fsdev/virtfs-proxy-helper.c
|
||||
+++ b/fsdev/virtfs-proxy-helper.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "qemu/xattr.h"
|
||||
#include "9p-iov-marshal.h"
|
||||
#include "hw/9pfs/9p-proxy.h"
|
||||
+#include "hw/9pfs/9p-util.h"
|
||||
#include "fsdev/9p-iov-marshal.h"
|
||||
|
||||
#define PROGNAME "virtfs-proxy-helper"
|
||||
@@ -338,6 +339,28 @@ static void resetugid(int suid, int sgid)
|
||||
}
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Open regular file or directory. Attempts to open any special file are
|
||||
+ * rejected.
|
||||
+ *
|
||||
+ * returns file descriptor or -1 on error
|
||||
+ */
|
||||
+static int open_regular(const char *pathname, int flags, mode_t mode)
|
||||
+{
|
||||
+ int fd;
|
||||
+
|
||||
+ fd = open(pathname, flags, mode);
|
||||
+ if (fd < 0) {
|
||||
+ return fd;
|
||||
+ }
|
||||
+
|
||||
+ if (close_if_special_file(fd) < 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return fd;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* send response in two parts
|
||||
* 1) ProxyHeader
|
||||
@@ -682,7 +705,7 @@ static int do_create(struct iovec *iovec)
|
||||
if (ret < 0) {
|
||||
goto unmarshal_err_out;
|
||||
}
|
||||
- ret = open(path.data, flags, mode);
|
||||
+ ret = open_regular(path.data, flags, mode);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
}
|
||||
@@ -707,7 +730,7 @@ static int do_open(struct iovec *iovec)
|
||||
if (ret < 0) {
|
||||
goto err_out;
|
||||
}
|
||||
- ret = open(path.data, flags);
|
||||
+ ret = open_regular(path.data, flags, 0);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
}
|
||||
diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h
|
||||
index 546f46dc7..54e270ac6 100644
|
||||
--- a/hw/9pfs/9p-util.h
|
||||
+++ b/hw/9pfs/9p-util.h
|
||||
@@ -13,6 +13,8 @@
|
||||
#ifndef QEMU_9P_UTIL_H
|
||||
#define QEMU_9P_UTIL_H
|
||||
|
||||
+#include "qemu/error-report.h"
|
||||
+
|
||||
#ifdef O_PATH
|
||||
#define O_PATH_9P_UTIL O_PATH
|
||||
#else
|
||||
@@ -26,6 +28,38 @@ static inline void close_preserve_errno(int fd)
|
||||
errno = serrno;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * close_if_special_file() - Close @fd if neither regular file nor directory.
|
||||
+ *
|
||||
+ * @fd: file descriptor of open file
|
||||
+ * Return: 0 on regular file or directory, -1 otherwise
|
||||
+ *
|
||||
+ * CVE-2023-2861: Prohibit opening any special file directly on host
|
||||
+ * (especially device files), as a compromised client could potentially gain
|
||||
+ * access outside exported tree under certain, unsafe setups. We expect
|
||||
+ * client to handle I/O on special files exclusively on guest side.
|
||||
+ */
|
||||
+static inline int close_if_special_file(int fd)
|
||||
+{
|
||||
+ struct stat stbuf;
|
||||
+
|
||||
+ if (qemu_fstat(fd, &stbuf) < 0) {
|
||||
+ close_preserve_errno(fd);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (!S_ISREG(stbuf.st_mode) && !S_ISDIR(stbuf.st_mode)) {
|
||||
+ error_report_once(
|
||||
+ "9p: broken or compromised client detected; attempt to open "
|
||||
+ "special file (i.e. neither regular file, nor directory)"
|
||||
+ );
|
||||
+ close(fd);
|
||||
+ errno = ENXIO;
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static inline int openat_dir(int dirfd, const char *name)
|
||||
{
|
||||
return openat(dirfd, name,
|
||||
@@ -56,6 +90,10 @@ again:
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ if (close_if_special_file(fd) < 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
serrno = errno;
|
||||
/* O_NONBLOCK was only needed to open the file. Let's drop it. We don't
|
||||
* do that with O_PATH since fcntl(F_SETFL) isn't supported, and openat()
|
||||
--
|
||||
2.40.0
|
||||
Reference in New Issue
Block a user