1[PATCH] Fix Double Free Corruption (CVE2012-1502) 2 3Downloaded from: 4http://pkgs.fedoraproject.org/cgit/PyPAM.git/plain/PyPAM-0.5.0-memory-errors.patch 5 6For details, see: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1502 7 8Signed-off-by: Peter Korsgaard <peter@korsgaard.com> 9diff -up PyPAM-0.5.0/PAMmodule.c.memory PyPAM-0.5.0/PAMmodule.c 10--- PyPAM-0.5.0/PAMmodule.c.memory 2012-05-07 17:22:54.503914026 +0200 11+++ PyPAM-0.5.0/PAMmodule.c 2012-05-07 17:23:15.644381942 +0200 12@@ -37,33 +37,48 @@ static void PyPAM_Err(PyPAMObject *self, 13 14 err_msg = pam_strerror(self->pamh, result); 15 error = Py_BuildValue("(si)", err_msg, result); 16- Py_INCREF(PyPAM_Error); 17 PyErr_SetObject(PyPAM_Error, error); 18+ Py_XDECREF(error); 19 } 20 21 static int PyPAM_conv(int num_msg, const struct pam_message **msg, 22 struct pam_response **resp, void *appdata_ptr) 23 { 24- PyObject *args; 25- 26+ PyObject *args, *msgList, *respList, *item; 27+ struct pam_response *response, *spr; 28 PyPAMObject* self = (PyPAMObject *) appdata_ptr; 29+ 30 if (self->callback == NULL) 31 return PAM_CONV_ERR; 32 33 Py_INCREF(self); 34 35- PyObject* msgList = PyList_New(num_msg); 36- 37+ msgList = PyList_New(num_msg); 38+ if (msgList == NULL) { 39+ Py_DECREF(self); 40+ return PAM_CONV_ERR; 41+ } 42+ 43 for (int i = 0; i < num_msg; i++) { 44- PyList_SetItem(msgList, i, 45- Py_BuildValue("(si)", msg[i]->msg, msg[i]->msg_style)); 46+ item = Py_BuildValue("(si)", msg[i]->msg, msg[i]->msg_style); 47+ if (item == NULL) { 48+ Py_DECREF(msgList); 49+ Py_DECREF(self); 50+ return PAM_CONV_ERR; 51+ } 52+ PyList_SetItem(msgList, i, item); 53 } 54- 55+ 56 args = Py_BuildValue("(OO)", self, msgList); 57- PyObject* respList = PyEval_CallObject(self->callback, args); 58+ if (args == NULL) { 59+ Py_DECREF(self); 60+ Py_DECREF(msgList); 61+ return PAM_CONV_ERR; 62+ } 63+ respList = PyEval_CallObject(self->callback, args); 64 Py_DECREF(args); 65 Py_DECREF(self); 66- 67+ 68 if (respList == NULL) 69 return PAM_CONV_ERR; 70 71@@ -71,11 +86,15 @@ static int PyPAM_conv(int num_msg, const 72 Py_DECREF(respList); 73 return PAM_CONV_ERR; 74 } 75- 76- *resp = (struct pam_response *) malloc( 77+ 78+ response = (struct pam_response *) malloc( 79 PyList_Size(respList) * sizeof(struct pam_response)); 80+ if (response == NULL) { 81+ Py_DECREF(respList); 82+ return PAM_CONV_ERR; 83+ } 84+ spr = response; 85 86- struct pam_response* spr = *resp; 87 for (int i = 0; i < PyList_Size(respList); i++, spr++) { 88 PyObject* respTuple = PyList_GetItem(respList, i); 89 char* resp_text; 90@@ -85,7 +104,7 @@ static int PyPAM_conv(int num_msg, const 91 free((--spr)->resp); 92 --i; 93 } 94- free(*resp); 95+ free(response); 96 Py_DECREF(respList); 97 return PAM_CONV_ERR; 98 } 99@@ -95,7 +114,8 @@ static int PyPAM_conv(int num_msg, const 100 } 101 102 Py_DECREF(respList); 103- 104+ *resp = response; 105+ 106 return PAM_SUCCESS; 107 } 108 109@@ -122,7 +142,11 @@ static PyObject * PyPAM_pam(PyObject *se 110 PyPAMObject_Type.ob_type = &PyType_Type; 111 p = (PyPAMObject *) PyObject_NEW(PyPAMObject, &PyPAMObject_Type); 112 113+ if (p == NULL) 114+ return NULL; 115+ 116 if ((spc = (struct pam_conv *) malloc(sizeof(struct pam_conv))) == NULL) { 117+ Py_DECREF((PyObject *)p); 118 PyErr_SetString(PyExc_MemoryError, "out of memory"); 119 return NULL; 120 } 121@@ -455,9 +479,15 @@ static PyObject * PyPAM_getenvlist(PyObj 122 } 123 124 retval = PyList_New(0); 125+ if (retval == NULL) 126+ return NULL; 127 128 while ((cp = *(result++)) != NULL) { 129 entry = Py_BuildValue("s", cp); 130+ if (entry == NULL) { 131+ Py_DECREF(retval); 132+ return NULL; 133+ } 134 PyList_Append(retval, entry); 135 Py_DECREF(entry); 136 } 137