summary refs log tree commit diff stats
path: root/hw/9pfs/9p-util.h
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-06-08 08:47:35 -0700
committerRichard Henderson <richard.henderson@linaro.org>2023-06-08 08:47:35 -0700
commit5f9dd6a8ce3961db4ce47411ed2097ad88bdf5fc (patch)
treeff8c37ba95f9fe4fd84bba1b225b8cb95b4c8d7a /hw/9pfs/9p-util.h
parent45ae97993a75f975f1a01d25564724c7e10a543f (diff)
parentf6b0de53fb87ddefed348a39284c8e2f28dc4eda (diff)
downloadfocaccia-qemu-5f9dd6a8ce3961db4ce47411ed2097ad88bdf5fc.tar.gz
focaccia-qemu-5f9dd6a8ce3961db4ce47411ed2097ad88bdf5fc.zip
Merge tag 'pull-9p-20230608' of https://github.com/cschoenebeck/qemu into staging
* Fix for CVE-2023-2861.

# -----BEGIN PGP SIGNATURE-----
#
# iQJLBAABCgA1FiEEltjREM96+AhPiFkBNMK1h2Wkc5UFAmSB7yMXHHFlbXVfb3Nz
# QGNydWRlYnl0ZS5jb20ACgkQNMK1h2Wkc5XykxAAzQb+d2clDVyj3Y3UqcB/YS7X
# ijxoZph9ObweyPiP2IThjsAcvNPnVR2Bc8bgEpihRkpEYGNLicw5BSk1SjqOgZvg
# buDRc8bOvOOrKqvYEBXbzaS/OHVIdozn8h+WNjX0jSsdUd4uq9vcwX+uqshkPwl+
# L4Ipx7ChzmHpaEigkVLh1biQEkLPRCTplny5JK/ZzvAmGVaqYb1usbSx//OVu7k+
# gBuBALmvJQst3iz/1e+bmVg+JhyxRqcHfCJuuWxaOLIyiZME3ZhTn7tp+2ilivRj
# n4/AGglTAv+yaVwRi6XEca7GND23HqFs26RPGgZrIhsAkFV03Iz3IT/BJ3Psy3Qv
# 7KYE4FhhReDnNU5JNfCbNxUPWVilwLY83BXVL9I0CADbAHgTqRSnataQ/PY26VQp
# BqKJKmxjAEnmsGVZSgRuCDDOhOBlPUPMRFINCUp2b0qujsUQaV5XHUlQ3qRfjUBc
# JQCy1LrxcSINg7oTRPZczNcrb9iWtaOfD24OGGeW1O6ihCAV0CYaRSmHUhFVPOPR
# uu4LWnbSToNgfNxBXaMk3vHA0SzWxJl7zBi53GVRvn8ciiTkAPVIoZLf0W8jE47X
# 5nkzfTpNdjnQJlaKAfDx+YcAyBUPxiknJjAJmjF/mquAtW8c9XbsCVJpyUgS4Lna
# GNfRoCUHQ6+6ui+/zM0=
# =6Vxp
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 08 Jun 2023 08:09:23 AM PDT
# gpg:                using RSA key 96D8D110CF7AF8084F88590134C2B58765A47395
# gpg:                issuer "qemu_oss@crudebyte.com"
# gpg: Good signature from "Christian Schoenebeck <qemu_oss@crudebyte.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: ECAB 1A45 4014 1413 BA38  4926 30DB 47C3 A012 D5F4
#      Subkey fingerprint: 96D8 D110 CF7A F808 4F88  5901 34C2 B587 65A4 7395

* tag 'pull-9p-20230608' of https://github.com/cschoenebeck/qemu:
  9pfs: prevent opening special files (CVE-2023-2861)

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw/9pfs/9p-util.h')
-rw-r--r--hw/9pfs/9p-util.h39
1 files changed, 39 insertions, 0 deletions
diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h
index c314cf381d..df1b583a5e 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
@@ -95,6 +97,7 @@ static inline int errno_to_dotl(int err) {
 #endif
 
 #define qemu_openat     openat
+#define qemu_fstat      fstat
 #define qemu_fstatat    fstatat
 #define qemu_mkdirat    mkdirat
 #define qemu_renameat   renameat
@@ -108,6 +111,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 qemu_openat(dirfd, name,
@@ -142,6 +177,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()