From bd8b54c469c4b4c61b3bc030e59b91101021f468 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Sat, 13 Jun 2026 16:41:35 +0300 Subject: [PATCH] sys: FspVolumeNotify: fix integer overflow vulnerability This vulnerability was reported by: - Tay Kiat Loong (GitHub: @owl4444) - uhg (GitHub: @UltimateHG) --- inc/winfsp/fsctl.h | 2 ++ src/sys/volume.c | 3 +++ tst/winfsp-tests/notify-test.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index a648537b..7528a8e5 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -147,6 +147,8 @@ FSP_FSCTL_STATIC_ASSERT(FSP_FSCTL_VOLUME_NAME_SIZEMAX <= 260 * sizeof(WCHAR), #define FSP_FSCTL_DEVICECONTROL_SIZEMAX (4 * 1024) /* must be < FSP_FSCTL_TRANSACT_{REQ,RSP}_SIZEMAX */ +#define FSP_FSCTL_NOTIFY_INFO_SIZEMAX (0x7fffffffU) + /* marshalling */ #pragma warning(push) #pragma warning(disable:4200 4201) /* zero-sized array in struct/union; nameless struct/union */ diff --git a/src/sys/volume.c b/src/sys/volume.c index 4f6c2576..d734cb4a 100644 --- a/src/sys/volume.c +++ b/src/sys/volume.c @@ -1389,6 +1389,9 @@ NTSTATUS FspVolumeNotify( if (0 == InputBufferLength) return FspVolumeNotifyLock(FsvolDeviceObject); + if (FSP_FSCTL_NOTIFY_INFO_SIZEMAX < InputBufferLength) + return STATUS_INVALID_PARAMETER; + if (!FspDeviceReference(FsvolDeviceObject)) return STATUS_CANCELLED; diff --git a/tst/winfsp-tests/notify-test.c b/tst/winfsp-tests/notify-test.c index 55e6572a..e6c062ea 100644 --- a/tst/winfsp-tests/notify-test.c +++ b/tst/winfsp-tests/notify-test.c @@ -27,6 +27,37 @@ #include "winfsp-tests.h" +static +void notify_invalid_dotest(ULONG Flags) +{ + void *memfs = memfs_start(Flags); + FSP_FILE_SYSTEM *FileSystem = MemfsFileSystem(memfs); + NTSTATUS Result; + + Result = FspFsctlNotify(FileSystem->VolumeHandle, 0, 1); + ASSERT(STATUS_ACCESS_VIOLATION == Result); + + Result = FspFsctlNotify(FileSystem->VolumeHandle, 0, FSP_FSCTL_NOTIFY_INFO_SIZEMAX); + ASSERT(STATUS_ACCESS_VIOLATION == Result || STATUS_INSUFFICIENT_RESOURCES == Result); + + Result = FspFsctlNotify(FileSystem->VolumeHandle, 0, FSP_FSCTL_NOTIFY_INFO_SIZEMAX + 1); + ASSERT(STATUS_INVALID_PARAMETER == Result); + + Result = FspFsctlNotify(FileSystem->VolumeHandle, 0, 0xffffffffU); + ASSERT(STATUS_INVALID_PARAMETER == Result); + + memfs_stop(memfs); +} + +static +void notify_invalid_test(void) +{ + if (WinFspDiskTests) + notify_invalid_dotest(MemfsDisk); + if (WinFspNetTests) + notify_invalid_dotest(MemfsNet); +} + static void notify_abandon_dotest(ULONG Flags) { @@ -479,6 +510,7 @@ void notify_tests(void) if (OptExternal || OptNotify) return; + TEST(notify_invalid_test); TEST(notify_abandon_test); TEST(notify_abandon_rename_test); /* OBSOLETE: it is now possible to have multiple outstanding NotifyBegin() calls. */