changeset: 103438:e524d5dc8767 branch: 2.7 parent: 103420:dbaf2cbf8f6f user: Steve Dower date: Fri Sep 09 11:56:34 2016 -0700 files: Misc/NEWS PC/_msi.c description: Issue #24594: Validates persist parameter when opening MSI database diff -r dbaf2cbf8f6f -r e524d5dc8767 Misc/NEWS --- a/Misc/NEWS Fri Sep 09 11:05:58 2016 -0700 +++ b/Misc/NEWS Fri Sep 09 11:56:34 2016 -0700 @@ -42,6 +42,8 @@ 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. diff -r dbaf2cbf8f6f -r e524d5dc8767 PC/_msi.c --- a/PC/_msi.c Fri Sep 09 11:05:58 2016 -0700 +++ b/PC/_msi.c Fri Sep 09 11:56:34 2016 -0700 @@ -938,6 +938,17 @@ 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 @@ 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);