qemu/9pfs-fix-crash-on-Treaddir-request.patch
Gan Qixin 95b7632436 QEMU update to version 6.2.0-104:
- intel_iommu: Add missed reserved bit check for IEC descriptor
- 9pfs: fix crash on 'Treaddir' request
- s390x/ap: fix missing subsystem reset registration
- qemu/bswap: Undefine CPU_CONVERT() once done
- linux-user: Add missing signals in strace output
- linux-user: Add missing clock_gettime64() syscall strace

Signed-off-by: Gan Qixin <ganqixin@huawei.com>
(cherry picked from commit 692bd89e009248b7108baa30dfb2fdeeb55a8bbd)
2024-12-18 09:32:07 +08:00

65 lines
2.7 KiB
Diff

From 4d4c15d8fac49731db7727c7f91b4184c2a95d78 Mon Sep 17 00:00:00 2001
From: Christian Schoenebeck <qemu_oss@crudebyte.com>
Date: Tue, 5 Nov 2024 11:25:26 +0100
Subject: [PATCH] 9pfs: fix crash on 'Treaddir' request
A bad (broken or malicious) 9p client (guest) could cause QEMU host to
crash by sending a 9p 'Treaddir' request with a numeric file ID (FID) that
was previously opened for a file instead of an expected directory:
#0 0x0000762aff8f4919 in __GI___rewinddir (dirp=0xf) at
../sysdeps/unix/sysv/linux/rewinddir.c:29
#1 0x0000557b7625fb40 in do_readdir_many (pdu=0x557bb67d2eb0,
fidp=0x557bb67955b0, entries=0x762afe9fff58, offset=0, maxsize=131072,
dostat=<optimized out>) at ../hw/9pfs/codir.c:101
#2 v9fs_co_readdir_many (pdu=pdu@entry=0x557bb67d2eb0,
fidp=fidp@entry=0x557bb67955b0, entries=entries@entry=0x762afe9fff58,
offset=0, maxsize=131072, dostat=false) at ../hw/9pfs/codir.c:226
#3 0x0000557b7625c1f9 in v9fs_do_readdir (pdu=0x557bb67d2eb0,
fidp=0x557bb67955b0, offset=<optimized out>,
max_count=<optimized out>) at ../hw/9pfs/9p.c:2488
#4 v9fs_readdir (opaque=0x557bb67d2eb0) at ../hw/9pfs/9p.c:2602
That's because V9fsFidOpenState was declared as union type. So the
same memory region is used for either an open POSIX file handle (int),
or a POSIX DIR* pointer, etc., so 9p server incorrectly used the
previously opened (valid) POSIX file handle (0xf) as DIR* pointer,
eventually causing a crash in glibc's rewinddir() function.
Root cause was therefore a missing check in 9p server's 'Treaddir'
request handler, which must ensure that the client supplied FID was
really opened as directory stream before trying to access the
aforementioned union and its DIR* member.
Cc: qemu-stable@nongnu.org
Fixes: d62dbb51f7 ("virtio-9p: Add fidtype so that we can do type ...")
Reported-by: Akihiro Suda <suda.kyoto@gmail.com>
Tested-by: Akihiro Suda <suda.kyoto@gmail.com>
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
Message-Id: <E1t8GnN-002RS8-E2@kylie.crudebyte.com>
Signed-off-by: Zhongrui Tang <tangzhongrui_yewu@cmss.chinamobile.com>
---
hw/9pfs/9p.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 15b3f4d385..4e52f26afe 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -2528,6 +2528,11 @@ static void coroutine_fn v9fs_readdir(void *opaque)
retval = -EINVAL;
goto out_nofid;
}
+ if (fidp->fid_type != P9_FID_DIR) {
+ warn_report_once("9p: bad client: T_readdir on non-directory stream");
+ retval = -ENOTDIR;
+ goto out;
+ }
if (!fidp->fs.dir.stream) {
retval = -EINVAL;
goto out;
--
2.33.0