Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 161577 Details for
Bug 232137
dev-lang/python Multiple vulnerabilities (CVE-2008-{3142,3143,3144})
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
python-2.4.4-CVE-2008-3142.patch
python-2.4.4-CVE-2008-3142.patch (text/plain), 7.49 KB, created by
Robert Buchholz (RETIRED)
on 2008-07-28 20:22:11 UTC
(
hide
)
Description:
python-2.4.4-CVE-2008-3142.patch
Filename:
MIME Type:
Creator:
Robert Buchholz (RETIRED)
Created:
2008-07-28 20:22:11 UTC
Size:
7.49 KB
patch
obsolete
>r65262 | neal.norwitz | 2008-07-28 07:22:45 +0200 (Mon, 28 Jul 2008) | 11 lines > >Backport r65182. This change modified from using the unsigned max value >to the signed max value similar to 2.5 and trunk. > >Issue #2620: Overflow checking when allocating or reallocating memory >was not always being done properly in some python types and extension >modules. PyMem_MALLOC, PyMem_REALLOC, PyMem_NEW and PyMem_RESIZE have >all been updated to perform better checks and places in the code that >would previously leak memory on the error path when such an allocation >failed have been fixed. > > >Index: Python-2.4.4/Include/pymem.h >=================================================================== >--- Python-2.4.4.orig/Include/pymem.h >+++ Python-2.4.4/Include/pymem.h >@@ -66,8 +66,12 @@ PyAPI_FUNC(void) PyMem_Free(void *); > for malloc(0), which would be treated as an error. Some platforms > would return a pointer with no memory behind it, which would break > pymalloc. To solve these problems, allocate an extra byte. */ >-#define PyMem_MALLOC(n) malloc((n) ? (n) : 1) >-#define PyMem_REALLOC(p, n) realloc((p), (n) ? (n) : 1) >+/* Returns NULL to indicate error if a negative size or size larger than >+ Py_ssize_t can represent is supplied. Helps prevents security holes. */ >+#define PyMem_MALLOC(n) (((n) < 0 || (n) > INT_MAX) ? NULL \ >+ : malloc((n) ? (n) : 1)) >+#define PyMem_REALLOC(p, n) (((n) < 0 || (n) > INT_MAX) ? NULL \ >+ : realloc((p), (n) ? (n) : 1)) > > #endif /* PYMALLOC_DEBUG */ > >@@ -80,24 +84,31 @@ PyAPI_FUNC(void) PyMem_Free(void *); > * Type-oriented memory interface > * ============================== > * >- * These are carried along for historical reasons. There's rarely a good >- * reason to use them anymore (you can just as easily do the multiply and >- * cast yourself). >+ * Allocate memory for n objects of the given type. Returns a new pointer >+ * or NULL if the request was too large or memory allocation failed. Use >+ * these macros rather than doing the multiplication yourself so that proper >+ * overflow checking is always done. > */ > > #define PyMem_New(type, n) \ >- ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \ >+ ( ((n) > INT_MAX / sizeof(type)) ? NULL : \ > ( (type *) PyMem_Malloc((n) * sizeof(type)) ) ) > #define PyMem_NEW(type, n) \ >- ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \ >+ ( ((n) > INT_MAX / sizeof(type)) ? NULL : \ > ( (type *) PyMem_MALLOC((n) * sizeof(type)) ) ) > >+/* >+ * The value of (p) is always clobbered by this macro regardless of success. >+ * The caller MUST check if (p) is NULL afterwards and deal with the memory >+ * error if so. This means the original value of (p) MUST be saved for the >+ * caller's memory error handler to not lose track of it. >+ */ > #define PyMem_Resize(p, type, n) \ >- ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \ >- ( (p) = (type *) PyMem_Realloc((p), (n) * sizeof(type)) ) ) >+ ( (p) = ((n) > INT_MAX / sizeof(type)) ? NULL : \ >+ (type *) PyMem_Realloc((p), (n) * sizeof(type)) ) > #define PyMem_RESIZE(p, type, n) \ >- ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \ >- ( (p) = (type *) PyMem_REALLOC((p), (n) * sizeof(type)) ) ) >+ ( (p) = ((n) > INT_MAX / sizeof(type)) ? NULL : \ >+ (type *) PyMem_REALLOC((p), (n) * sizeof(type)) ) > > /* In order to avoid breaking old code mixing PyObject_{New, NEW} with > PyMem_{Del, DEL} and PyMem_{Free, FREE}, the PyMem "release memory" >Index: Python-2.4.4/Objects/obmalloc.c >=================================================================== >--- Python-2.4.4.orig/Objects/obmalloc.c >+++ Python-2.4.4/Objects/obmalloc.c >@@ -585,6 +585,15 @@ PyObject_Malloc(size_t nbytes) > uint size; > > /* >+ * Limit ourselves to INT_MAX bytes to prevent security holes. >+ * Most python internals blindly use a signed Py_ssize_t to track >+ * things without checking for overflows or negatives. >+ * As size_t is unsigned, checking for nbytes < 0 is not required. >+ */ >+ if (nbytes > INT_MAX) >+ return NULL; >+ >+ /* > * This implicitly redirects malloc(0). > */ > if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) { >@@ -814,6 +823,15 @@ PyObject_Realloc(void *p, size_t nbytes) > if (p == NULL) > return PyObject_Malloc(nbytes); > >+ /* >+ * Limit ourselves to INT_MAX bytes to prevent security holes. >+ * Most python internals blindly use a signed Py_ssize_t to track >+ * things without checking for overflows or negatives. >+ * As size_t is unsigned, checking for nbytes < 0 is not required. >+ */ >+ if (nbytes > INT_MAX) >+ return NULL; >+ > pool = POOL_ADDR(p); > if (Py_ADDRESS_IN_RANGE(p, pool)) { > /* We're in charge of this block */ >Index: Python-2.4.4/Misc/NEWS >=================================================================== >--- Python-2.4.4.orig/Misc/NEWS >+++ Python-2.4.4/Misc/NEWS >@@ -23,6 +23,13 @@ What's New in Python 2.4.4c1? > Core and builtins > ----------------- > >+- Issue #2620: Overflow checking when allocating or reallocating memory >+ was not always being done properly in some python types and extension >+ modules. PyMem_MALLOC, PyMem_REALLOC, PyMem_NEW and PyMem_RESIZE have >+ all been updated to perform better checks and places in the code that >+ would previously leak memory on the error path when such an allocation >+ failed have been fixed. >+ > - Added checks for integer overflows, contributed by Google. Some are > only available if asserts are left in the code, in cases where they > can't be triggered from Python code. >Index: Python-2.4.4/Modules/almodule.c >=================================================================== >--- Python-2.4.4.orig/Modules/almodule.c >+++ Python-2.4.4/Modules/almodule.c >@@ -1633,9 +1633,11 @@ al_QueryValues(PyObject *self, PyObject > if (nvals < 0) > goto cleanup; > if (nvals > setsize) { >+ ALvalue *old_return_set = return_set; > setsize = nvals; > PyMem_RESIZE(return_set, ALvalue, setsize); > if (return_set == NULL) { >+ return_set = old_return_set; > PyErr_NoMemory(); > goto cleanup; > } >Index: Python-2.4.4/Modules/arraymodule.c >=================================================================== >--- Python-2.4.4.orig/Modules/arraymodule.c >+++ Python-2.4.4/Modules/arraymodule.c >@@ -814,6 +814,7 @@ static int > array_do_extend(arrayobject *self, PyObject *bb) > { > int size; >+ char *old_item; > > if (!array_Check(bb)) > return array_iter_extend(self, bb); >@@ -829,10 +830,11 @@ array_do_extend(arrayobject *self, PyObj > return -1; > } > size = self->ob_size + b->ob_size; >+ old_item = self->ob_item; > PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize); > if (self->ob_item == NULL) { >- PyObject_Del(self); >- PyErr_NoMemory(); >+ self->ob_item = old_item; >+ PyErr_NoMemory(); > return -1; > } > memcpy(self->ob_item + self->ob_size*self->ob_descr->itemsize, >@@ -884,7 +886,7 @@ array_inplace_repeat(arrayobject *self, > if (size > INT_MAX / n) { > return PyErr_NoMemory(); > } >- PyMem_Resize(items, char, n * size); >+ PyMem_RESIZE(items, char, n * size); > if (items == NULL) > return PyErr_NoMemory(); > p = items; >Index: Python-2.4.4/Modules/selectmodule.c >=================================================================== >--- Python-2.4.4.orig/Modules/selectmodule.c >+++ Python-2.4.4/Modules/selectmodule.c >@@ -342,10 +342,12 @@ update_ufd_array(pollObject *self) > { > int i, pos; > PyObject *key, *value; >+ struct pollfd *old_ufds = self->ufds; > > self->ufd_len = PyDict_Size(self->dict); >- PyMem_Resize(self->ufds, struct pollfd, self->ufd_len); >+ PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len); > if (self->ufds == NULL) { >+ self->ufds = old_ufds; > PyErr_NoMemory(); > return 0; > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 232137
:
160679
| 161577 |
161579