| [PATCH] Fix Double Free Corruption (CVE2012-1502) |
| |
| Downloaded from: |
| http://pkgs.fedoraproject.org/cgit/PyPAM.git/plain/PyPAM-0.5.0-memory-errors.patch |
| |
| For details, see: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1502 |
| |
| Signed-off-by: Peter Korsgaard <peter@korsgaard.com> |
| diff -up PyPAM-0.5.0/PAMmodule.c.memory PyPAM-0.5.0/PAMmodule.c |
| --- PyPAM-0.5.0/PAMmodule.c.memory 2012-05-07 17:22:54.503914026 +0200 |
| +++ PyPAM-0.5.0/PAMmodule.c 2012-05-07 17:23:15.644381942 +0200 |
| @@ -37,33 +37,48 @@ static void PyPAM_Err(PyPAMObject *self, |
| |
| err_msg = pam_strerror(self->pamh, result); |
| error = Py_BuildValue("(si)", err_msg, result); |
| - Py_INCREF(PyPAM_Error); |
| PyErr_SetObject(PyPAM_Error, error); |
| + Py_XDECREF(error); |
| } |
| |
| static int PyPAM_conv(int num_msg, const struct pam_message **msg, |
| struct pam_response **resp, void *appdata_ptr) |
| { |
| - PyObject *args; |
| - |
| + PyObject *args, *msgList, *respList, *item; |
| + struct pam_response *response, *spr; |
| PyPAMObject* self = (PyPAMObject *) appdata_ptr; |
| + |
| if (self->callback == NULL) |
| return PAM_CONV_ERR; |
| |
| Py_INCREF(self); |
| |
| - PyObject* msgList = PyList_New(num_msg); |
| - |
| + msgList = PyList_New(num_msg); |
| + if (msgList == NULL) { |
| + Py_DECREF(self); |
| + return PAM_CONV_ERR; |
| + } |
| + |
| for (int i = 0; i < num_msg; i++) { |
| - PyList_SetItem(msgList, i, |
| - Py_BuildValue("(si)", msg[i]->msg, msg[i]->msg_style)); |
| + item = Py_BuildValue("(si)", msg[i]->msg, msg[i]->msg_style); |
| + if (item == NULL) { |
| + Py_DECREF(msgList); |
| + Py_DECREF(self); |
| + return PAM_CONV_ERR; |
| + } |
| + PyList_SetItem(msgList, i, item); |
| } |
| - |
| + |
| args = Py_BuildValue("(OO)", self, msgList); |
| - PyObject* respList = PyEval_CallObject(self->callback, args); |
| + if (args == NULL) { |
| + Py_DECREF(self); |
| + Py_DECREF(msgList); |
| + return PAM_CONV_ERR; |
| + } |
| + respList = PyEval_CallObject(self->callback, args); |
| Py_DECREF(args); |
| Py_DECREF(self); |
| - |
| + |
| if (respList == NULL) |
| return PAM_CONV_ERR; |
| |
| @@ -71,11 +86,15 @@ static int PyPAM_conv(int num_msg, const |
| Py_DECREF(respList); |
| return PAM_CONV_ERR; |
| } |
| - |
| - *resp = (struct pam_response *) malloc( |
| + |
| + response = (struct pam_response *) malloc( |
| PyList_Size(respList) * sizeof(struct pam_response)); |
| + if (response == NULL) { |
| + Py_DECREF(respList); |
| + return PAM_CONV_ERR; |
| + } |
| + spr = response; |
| |
| - struct pam_response* spr = *resp; |
| for (int i = 0; i < PyList_Size(respList); i++, spr++) { |
| PyObject* respTuple = PyList_GetItem(respList, i); |
| char* resp_text; |
| @@ -85,7 +104,7 @@ static int PyPAM_conv(int num_msg, const |
| free((--spr)->resp); |
| --i; |
| } |
| - free(*resp); |
| + free(response); |
| Py_DECREF(respList); |
| return PAM_CONV_ERR; |
| } |
| @@ -95,7 +114,8 @@ static int PyPAM_conv(int num_msg, const |
| } |
| |
| Py_DECREF(respList); |
| - |
| + *resp = response; |
| + |
| return PAM_SUCCESS; |
| } |
| |
| @@ -122,7 +142,11 @@ static PyObject * PyPAM_pam(PyObject *se |
| PyPAMObject_Type.ob_type = &PyType_Type; |
| p = (PyPAMObject *) PyObject_NEW(PyPAMObject, &PyPAMObject_Type); |
| |
| + if (p == NULL) |
| + return NULL; |
| + |
| if ((spc = (struct pam_conv *) malloc(sizeof(struct pam_conv))) == NULL) { |
| + Py_DECREF((PyObject *)p); |
| PyErr_SetString(PyExc_MemoryError, "out of memory"); |
| return NULL; |
| } |
| @@ -455,9 +479,15 @@ static PyObject * PyPAM_getenvlist(PyObj |
| } |
| |
| retval = PyList_New(0); |
| + if (retval == NULL) |
| + return NULL; |
| |
| while ((cp = *(result++)) != NULL) { |
| entry = Py_BuildValue("s", cp); |
| + if (entry == NULL) { |
| + Py_DECREF(retval); |
| + return NULL; |
| + } |
| PyList_Append(retval, entry); |
| Py_DECREF(entry); |
| } |