[PATCH 5/7] ntdll: relax input buffer size check on IOCTL_DVD_READ_STRUCTURE (resend)

Dan Kegel dank at kegel.com
Fri Feb 10 14:30:31 CST 2012


Apps that define their own DVD_READ_STRUCTURE (to avoid needing the ddk)
and forget to pack it end up with pad bytes on the end of that struct.
Windows acepts this without complaint, so relax the input buffer size check.
---
 dlls/kernel32/tests/cdrom.c |   40 ++++++++++++++++++++++++++++++++++++++++
 dlls/ntdll/cdrom.c          |    2 +-
 2 files changed, 41 insertions(+), 1 deletions(-)

diff --git a/dlls/kernel32/tests/cdrom.c b/dlls/kernel32/tests/cdrom.c
index f8e1968..ed9abbe 100644
--- a/dlls/kernel32/tests/cdrom.c
+++ b/dlls/kernel32/tests/cdrom.c
@@ -41,6 +41,45 @@ typedef struct xDVD_LAYER_DESCRIPTOR {
 
 #include <poppack.h>
 
+#define HUGEBUF 8192   /* Larger than ever needed */
+
+/* Try IOCTL_DVD_READ_STRUCTURE with various sizes of input buffer */
+static void test_readStruct_input(HANDLE hdevice)
+{
+    static struct {
+        int ilen;
+        BOOL ret;
+        DWORD err;
+    } cases[] = {
+        {sizeof(DVD_READ_STRUCTURE)-1, FALSE, ERROR_INVALID_PARAMETER},
+        {sizeof(DVD_READ_STRUCTURE),   TRUE,  0},
+        {sizeof(DVD_READ_STRUCTURE)+1, TRUE,  0},
+        {0}
+    };
+    char ibuf[HUGEBUF];
+    int i;
+
+    ZeroMemory(&ibuf, sizeof(ibuf));
+
+    for (i=0; cases[i].ilen; i++) {
+        char obuf[HUGEBUF];
+        DWORD bytes_read = 0;
+        BOOL bResult;
+        bResult = DeviceIoControl(hdevice, IOCTL_DVD_READ_STRUCTURE,
+                                  ibuf, cases[i].ilen,
+                                  obuf, sizeof(obuf), &bytes_read, 0);
+        ok(bResult == cases[i].ret,
+           "case %d: DeviceIoControl returned %d, expected %d\n",
+           i, bResult, cases[i].ret);
+        if (cases[i].err) {
+            DWORD err = GetLastError();
+            ok(err == cases[i].err,
+               "case %d: Last error was %d, expected %d\n",
+               i, err, cases[i].err);
+        }
+    }
+}
+
 /* Backdoor way to do the same thing as IOCTL_DVD_READ_STRUCTURE */
 DWORD read_discStructure(HANDLE device, int format, void *obuf, int obuflen)
 {
@@ -150,6 +189,7 @@ START_TEST(cdrom)
         skip("can't read DVD info from %s\n", drivepath);
     } else {
         /* DVD tests */
+        test_readStruct_input(hdevice);
         test_readStruct_layer_vs_passthrough(hdevice);
     }
     CloseHandle(hdevice);
diff --git a/dlls/ntdll/cdrom.c b/dlls/ntdll/cdrom.c
index 6b64203c..b151983 100644
--- a/dlls/ntdll/cdrom.c
+++ b/dlls/ntdll/cdrom.c
@@ -3099,7 +3099,7 @@ NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
         break;
     case IOCTL_DVD_READ_STRUCTURE:
         sz = sizeof(DVD_LAYER_DESCRIPTOR);
-        if (lpInBuffer == NULL || nInBufferSize != sizeof(DVD_READ_STRUCTURE)) status = STATUS_INVALID_PARAMETER;
+        if (lpInBuffer == NULL || nInBufferSize < sizeof(DVD_READ_STRUCTURE)) status = STATUS_INVALID_PARAMETER;
         else if (nOutBufferSize < sz) status = STATUS_BUFFER_TOO_SMALL;
         else
         {
-- 
1.7.9




More information about the wine-patches mailing list