]> granicus.if.org Git - python/commitdiff
Issue #24594: Validates persist parameter when opening MSI database
authorSteve Dower <steve.dower@microsoft.com>
Fri, 9 Sep 2016 18:56:34 +0000 (11:56 -0700)
committerSteve Dower <steve.dower@microsoft.com>
Fri, 9 Sep 2016 18:56:34 +0000 (11:56 -0700)
Misc/NEWS
PC/_msi.c

index 31a91bf70bf737fac53e8cd0246960a9b66b3c19..63ec3bfaf76e21449dd2e400903f2fb406c83d9a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -42,6 +42,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #24594: Validates persist parameter when opening MSI database
+
 - Issue #27570: Avoid zero-length memcpy() etc calls with null source
   pointers in the "ctypes" and "array" modules.
 
index 574dddec0582098b8872cd25e5c3582a47bef9b3..d56b5d10dc96c0f016dbda1ee0fb0d0784c49a43 100644 (file)
--- a/PC/_msi.c
+++ b/PC/_msi.c
@@ -938,6 +938,17 @@ static PyTypeObject msidb_Type = {
         0,                      /*tp_is_gc*/
 };
 
+#define Py_NOT_PERSIST(x, flag)                        \
+    (x != (int)(flag) &&                      \
+    x != ((int)(flag) | MSIDBOPEN_PATCHFILE))
+
+#define Py_INVALID_PERSIST(x)                \
+    (Py_NOT_PERSIST(x, MSIDBOPEN_READONLY) &&  \
+    Py_NOT_PERSIST(x, MSIDBOPEN_TRANSACT) &&   \
+    Py_NOT_PERSIST(x, MSIDBOPEN_DIRECT) &&     \
+    Py_NOT_PERSIST(x, MSIDBOPEN_CREATE) &&     \
+    Py_NOT_PERSIST(x, MSIDBOPEN_CREATEDIRECT))
+
 static PyObject* msiopendb(PyObject *obj, PyObject *args)
 {
     int status;
@@ -945,11 +956,14 @@ static PyObject* msiopendb(PyObject *obj, PyObject *args)
     int persist;
     MSIHANDLE h;
     msiobj *result;
-
     if (!PyArg_ParseTuple(args, "si:MSIOpenDatabase", &path, &persist))
         return NULL;
-
-        status = MsiOpenDatabase(path, (LPCSTR)persist, &h);
+    /* We need to validate that persist is a valid MSIDBOPEN_* value. Otherwise,
+       MsiOpenDatabase may treat the value as a pointer, leading to unexpected
+       behavior. */
+    if (Py_INVALID_PERSIST(persist))
+        return msierror(ERROR_INVALID_PARAMETER);
+    status = MsiOpenDatabase(path, (LPCSTR)persist, &h);
     if (status != ERROR_SUCCESS)
         return msierror(status);