aboutsummaryrefslogtreecommitdiff
path: root/fsdev
diff options
context:
space:
mode:
authorChristian Schoenebeck <qemu_oss@crudebyte.com>2023-06-07 18:29:33 +0200
committerChristian Schoenebeck <qemu_oss@crudebyte.com>2023-06-08 17:04:58 +0200
commitf6b0de53fb87ddefed348a39284c8e2f28dc4eda (patch)
treeff8c37ba95f9fe4fd84bba1b225b8cb95b4c8d7a /fsdev
parent45ae97993a75f975f1a01d25564724c7e10a543f (diff)
downloadqemu-f6b0de53fb87ddefed348a39284c8e2f28dc4eda.zip
qemu-f6b0de53fb87ddefed348a39284c8e2f28dc4eda.tar.gz
qemu-f6b0de53fb87ddefed348a39284c8e2f28dc4eda.tar.bz2
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>
Diffstat (limited to 'fsdev')
-rw-r--r--fsdev/virtfs-proxy-helper.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
index 5cafcd7..d9511f4 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"
@@ -339,6 +340,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
* 2) Response or error status
@@ -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;
}