View | Details | Raw Unified
Collapse All | Expand All

(-) Python-2.4.4/Include/pymem.h (-11 / +22 lines)
 Lines 66-73   PyAPI_FUNC(void) PyMem_Free(void *); Link Here 
   for malloc(0), which would be treated as an error. Some platforms
   for malloc(0), which would be treated as an error. Some platforms
   would return a pointer with no memory behind it, which would break
   would return a pointer with no memory behind it, which would break
   pymalloc. To solve these problems, allocate an extra byte. */
   pymalloc. To solve these problems, allocate an extra byte. */
#define PyMem_MALLOC(n)         malloc((n) ? (n) : 1)
/* Returns NULL to indicate error if a negative size or size larger than
#define PyMem_REALLOC(p, n)     realloc((p), (n) ? (n) : 1)
   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 */
#endif	/* PYMALLOC_DEBUG */
 Lines 80-103   PyAPI_FUNC(void) PyMem_Free(void *); Link Here 
 * Type-oriented memory interface
 * Type-oriented memory interface
 * ==============================
 * ==============================
 *
 *
 * These are carried along for historical reasons.  There's rarely a good
 * Allocate memory for n objects of the given type.  Returns a new pointer
 * reason to use them anymore (you can just as easily do the multiply and
 * or NULL if the request was too large or memory allocation failed.  Use
 * cast yourself).
 * these macros rather than doing the multiplication yourself so that proper
 * overflow checking is always done.
 */
 */
#define PyMem_New(type, n) \
#define PyMem_New(type, n) \
  ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
  ( ((n) > INT_MAX / sizeof(type)) ? NULL : \
	( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
	( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
#define PyMem_NEW(type, n) \
#define PyMem_NEW(type, n) \
  ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
  ( ((n) > INT_MAX / sizeof(type)) ? NULL : \
	( (type *) PyMem_MALLOC((n) * sizeof(type)) ) )
	( (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) \
#define PyMem_Resize(p, type, n) \
  ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
  ( (p) = ((n) > INT_MAX / sizeof(type)) ? NULL : \
	( (p) = (type *) PyMem_Realloc((p), (n) * sizeof(type)) ) )
	(type *) PyMem_Realloc((p), (n) * sizeof(type)) )
#define PyMem_RESIZE(p, type, n) \
#define PyMem_RESIZE(p, type, n) \
  ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
  ( (p) = ((n) > INT_MAX / sizeof(type)) ? NULL : \
	( (p) = (type *) PyMem_REALLOC((p), (n) * sizeof(type)) ) )
	(type *) PyMem_REALLOC((p), (n) * sizeof(type)) )
/* In order to avoid breaking old code mixing PyObject_{New, NEW} with
/* In order to avoid breaking old code mixing PyObject_{New, NEW} with
   PyMem_{Del, DEL} and PyMem_{Free, FREE}, the PyMem "release memory"
   PyMem_{Del, DEL} and PyMem_{Free, FREE}, the PyMem "release memory"
(-) Python-2.4.4/Objects/obmalloc.c (+18 lines)
 Lines 585-590   PyObject_Malloc(size_t nbytes) Link Here 
	uint size;
	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).
	 * This implicitly redirects malloc(0).
	 */
	 */
	if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) {
	if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) {
 Lines 814-819   PyObject_Realloc(void *p, size_t nbytes) Link Here 
	if (p == NULL)
	if (p == NULL)
		return PyObject_Malloc(nbytes);
		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);
	pool = POOL_ADDR(p);
	if (Py_ADDRESS_IN_RANGE(p, pool)) {
	if (Py_ADDRESS_IN_RANGE(p, pool)) {
		/* We're in charge of this block */
		/* We're in charge of this block */
(-) Python-2.4.4/Misc/NEWS (+7 lines)
 Lines 23-28   What's New in Python 2.4.4c1? Link Here 
Core and builtins
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
- Added checks for integer overflows, contributed by Google. Some are
  only available if asserts are left in the code, in cases where they
  only available if asserts are left in the code, in cases where they
  can't be triggered from Python code.
  can't be triggered from Python code.
(-) Python-2.4.4/Modules/almodule.c (+2 lines)
 Lines 1633-1641   al_QueryValues(PyObject *self, PyObject Link Here 
	if (nvals < 0)
	if (nvals < 0)
		goto cleanup;
		goto cleanup;
	if (nvals > setsize) {
	if (nvals > setsize) {
		ALvalue *old_return_set = return_set;
		setsize = nvals;
		setsize = nvals;
		PyMem_RESIZE(return_set, ALvalue, setsize);
		PyMem_RESIZE(return_set, ALvalue, setsize);
		if (return_set == NULL) {
		if (return_set == NULL) {
			return_set = old_return_set;
			PyErr_NoMemory();
			PyErr_NoMemory();
			goto cleanup;
			goto cleanup;
		}
		}
(-) Python-2.4.4/Modules/arraymodule.c (-3 / +5 lines)
 Lines 814-819   static int Link Here 
array_do_extend(arrayobject *self, PyObject *bb)
array_do_extend(arrayobject *self, PyObject *bb)
{
{
	int size;
	int size;
	char *old_item;
	if (!array_Check(bb))
	if (!array_Check(bb))
		return array_iter_extend(self, bb);
		return array_iter_extend(self, bb);
 Lines 829-838   array_do_extend(arrayobject *self, PyObj Link Here 
			return -1;
			return -1;
	}
	}
	size = self->ob_size + b->ob_size;
	size = self->ob_size + b->ob_size;
	old_item = self->ob_item;
        PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize);
        PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize);
        if (self->ob_item == NULL) {
        if (self->ob_item == NULL) {
                PyObject_Del(self);
		self->ob_item = old_item;
                PyErr_NoMemory();
		PyErr_NoMemory();
		return -1;
		return -1;
        }
        }
	memcpy(self->ob_item + self->ob_size*self->ob_descr->itemsize,
	memcpy(self->ob_item + self->ob_size*self->ob_descr->itemsize,
 Lines 884-890   array_inplace_repeat(arrayobject *self, Link Here 
			if (size > INT_MAX / n) {
			if (size > INT_MAX / n) {
				return PyErr_NoMemory();
				return PyErr_NoMemory();
			}
			}
			PyMem_Resize(items, char, n * size);
			PyMem_RESIZE(items, char, n * size);
			if (items == NULL)
			if (items == NULL)
				return PyErr_NoMemory();
				return PyErr_NoMemory();
			p = items;
			p = items;
(-) Python-2.4.4/Modules/selectmodule.c (-1 / +3 lines)
 Lines 342-351   update_ufd_array(pollObject *self) Link Here 
{
{
	int i, pos;
	int i, pos;
	PyObject *key, *value;
	PyObject *key, *value;
        struct pollfd *old_ufds = self->ufds;
	self->ufd_len = PyDict_Size(self->dict);
	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) {
	if (self->ufds == NULL) {
                self->ufds = old_ufds;
		PyErr_NoMemory();
		PyErr_NoMemory();
		return 0;
		return 0;
	}
	}