Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 232137 | Differences between
and this patch

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
66
   for malloc(0), which would be treated as an error. Some platforms
66
   for malloc(0), which would be treated as an error. Some platforms
67
   would return a pointer with no memory behind it, which would break
67
   would return a pointer with no memory behind it, which would break
68
   pymalloc. To solve these problems, allocate an extra byte. */
68
   pymalloc. To solve these problems, allocate an extra byte. */
69
#define PyMem_MALLOC(n)         malloc((n) ? (n) : 1)
69
/* Returns NULL to indicate error if a negative size or size larger than
70
#define PyMem_REALLOC(p, n)     realloc((p), (n) ? (n) : 1)
70
   Py_ssize_t can represent is supplied.  Helps prevents security holes. */
71
#define PyMem_MALLOC(n)		(((n) < 0 || (n) > INT_MAX) ? NULL \
72
				: malloc((n) ? (n) : 1))
73
#define PyMem_REALLOC(p, n)	(((n) < 0 || (n) > INT_MAX) ? NULL \
74
				: realloc((p), (n) ? (n) : 1))
71
75
72
#endif	/* PYMALLOC_DEBUG */
76
#endif	/* PYMALLOC_DEBUG */
73
77
Lines 80-103 PyAPI_FUNC(void) PyMem_Free(void *); Link Here
80
 * Type-oriented memory interface
84
 * Type-oriented memory interface
81
 * ==============================
85
 * ==============================
82
 *
86
 *
83
 * These are carried along for historical reasons.  There's rarely a good
87
 * Allocate memory for n objects of the given type.  Returns a new pointer
84
 * reason to use them anymore (you can just as easily do the multiply and
88
 * or NULL if the request was too large or memory allocation failed.  Use
85
 * cast yourself).
89
 * these macros rather than doing the multiplication yourself so that proper
90
 * overflow checking is always done.
86
 */
91
 */
87
92
88
#define PyMem_New(type, n) \
93
#define PyMem_New(type, n) \
89
  ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
94
  ( ((n) > INT_MAX / sizeof(type)) ? NULL : \
90
	( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
95
	( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
91
#define PyMem_NEW(type, n) \
96
#define PyMem_NEW(type, n) \
92
  ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
97
  ( ((n) > INT_MAX / sizeof(type)) ? NULL : \
93
	( (type *) PyMem_MALLOC((n) * sizeof(type)) ) )
98
	( (type *) PyMem_MALLOC((n) * sizeof(type)) ) )
94
99
100
/*
101
 * The value of (p) is always clobbered by this macro regardless of success.
102
 * The caller MUST check if (p) is NULL afterwards and deal with the memory
103
 * error if so.  This means the original value of (p) MUST be saved for the
104
 * caller's memory error handler to not lose track of it.
105
 */
95
#define PyMem_Resize(p, type, n) \
106
#define PyMem_Resize(p, type, n) \
96
  ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
107
  ( (p) = ((n) > INT_MAX / sizeof(type)) ? NULL : \
97
	( (p) = (type *) PyMem_Realloc((p), (n) * sizeof(type)) ) )
108
	(type *) PyMem_Realloc((p), (n) * sizeof(type)) )
98
#define PyMem_RESIZE(p, type, n) \
109
#define PyMem_RESIZE(p, type, n) \
99
  ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
110
  ( (p) = ((n) > INT_MAX / sizeof(type)) ? NULL : \
100
	( (p) = (type *) PyMem_REALLOC((p), (n) * sizeof(type)) ) )
111
	(type *) PyMem_REALLOC((p), (n) * sizeof(type)) )
101
112
102
/* In order to avoid breaking old code mixing PyObject_{New, NEW} with
113
/* In order to avoid breaking old code mixing PyObject_{New, NEW} with
103
   PyMem_{Del, DEL} and PyMem_{Free, FREE}, the PyMem "release memory"
114
   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
585
	uint size;
585
	uint size;
586
586
587
	/*
587
	/*
588
	 * Limit ourselves to INT_MAX bytes to prevent security holes.
589
	 * Most python internals blindly use a signed Py_ssize_t to track
590
	 * things without checking for overflows or negatives.
591
	 * As size_t is unsigned, checking for nbytes < 0 is not required.
592
	 */
593
	if (nbytes > INT_MAX)
594
		return NULL;
595
596
	/*
588
	 * This implicitly redirects malloc(0).
597
	 * This implicitly redirects malloc(0).
589
	 */
598
	 */
590
	if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) {
599
	if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) {
Lines 814-819 PyObject_Realloc(void *p, size_t nbytes) Link Here
814
	if (p == NULL)
823
	if (p == NULL)
815
		return PyObject_Malloc(nbytes);
824
		return PyObject_Malloc(nbytes);
816
825
826
	/*
827
	 * Limit ourselves to INT_MAX bytes to prevent security holes.
828
	 * Most python internals blindly use a signed Py_ssize_t to track
829
	 * things without checking for overflows or negatives.
830
	 * As size_t is unsigned, checking for nbytes < 0 is not required.
831
	 */
832
	if (nbytes > INT_MAX)
833
		return NULL;
834
817
	pool = POOL_ADDR(p);
835
	pool = POOL_ADDR(p);
818
	if (Py_ADDRESS_IN_RANGE(p, pool)) {
836
	if (Py_ADDRESS_IN_RANGE(p, pool)) {
819
		/* We're in charge of this block */
837
		/* 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
23
Core and builtins
23
Core and builtins
24
-----------------
24
-----------------
25
25
26
- Issue #2620: Overflow checking when allocating or reallocating memory
27
  was not always being done properly in some python types and extension
28
  modules.  PyMem_MALLOC, PyMem_REALLOC, PyMem_NEW and PyMem_RESIZE have
29
  all been updated to perform better checks and places in the code that
30
  would previously leak memory on the error path when such an allocation
31
  failed have been fixed.
32
26
- Added checks for integer overflows, contributed by Google. Some are
33
- Added checks for integer overflows, contributed by Google. Some are
27
  only available if asserts are left in the code, in cases where they
34
  only available if asserts are left in the code, in cases where they
28
  can't be triggered from Python code.
35
  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
1633
	if (nvals < 0)
1633
	if (nvals < 0)
1634
		goto cleanup;
1634
		goto cleanup;
1635
	if (nvals > setsize) {
1635
	if (nvals > setsize) {
1636
		ALvalue *old_return_set = return_set;
1636
		setsize = nvals;
1637
		setsize = nvals;
1637
		PyMem_RESIZE(return_set, ALvalue, setsize);
1638
		PyMem_RESIZE(return_set, ALvalue, setsize);
1638
		if (return_set == NULL) {
1639
		if (return_set == NULL) {
1640
			return_set = old_return_set;
1639
			PyErr_NoMemory();
1641
			PyErr_NoMemory();
1640
			goto cleanup;
1642
			goto cleanup;
1641
		}
1643
		}
(-)Python-2.4.4/Modules/arraymodule.c (-3 / +5 lines)
Lines 814-819 static int Link Here
814
array_do_extend(arrayobject *self, PyObject *bb)
814
array_do_extend(arrayobject *self, PyObject *bb)
815
{
815
{
816
	int size;
816
	int size;
817
	char *old_item;
817
818
818
	if (!array_Check(bb))
819
	if (!array_Check(bb))
819
		return array_iter_extend(self, bb);
820
		return array_iter_extend(self, bb);
Lines 829-838 array_do_extend(arrayobject *self, PyObj Link Here
829
			return -1;
830
			return -1;
830
	}
831
	}
831
	size = self->ob_size + b->ob_size;
832
	size = self->ob_size + b->ob_size;
833
	old_item = self->ob_item;
832
        PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize);
834
        PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize);
833
        if (self->ob_item == NULL) {
835
        if (self->ob_item == NULL) {
834
                PyObject_Del(self);
836
		self->ob_item = old_item;
835
                PyErr_NoMemory();
837
		PyErr_NoMemory();
836
		return -1;
838
		return -1;
837
        }
839
        }
838
	memcpy(self->ob_item + self->ob_size*self->ob_descr->itemsize,
840
	memcpy(self->ob_item + self->ob_size*self->ob_descr->itemsize,
Lines 884-890 array_inplace_repeat(arrayobject *self, Link Here
884
			if (size > INT_MAX / n) {
886
			if (size > INT_MAX / n) {
885
				return PyErr_NoMemory();
887
				return PyErr_NoMemory();
886
			}
888
			}
887
			PyMem_Resize(items, char, n * size);
889
			PyMem_RESIZE(items, char, n * size);
888
			if (items == NULL)
890
			if (items == NULL)
889
				return PyErr_NoMemory();
891
				return PyErr_NoMemory();
890
			p = items;
892
			p = items;
(-)Python-2.4.4/Modules/selectmodule.c (-1 / +3 lines)
Lines 342-351 update_ufd_array(pollObject *self) Link Here
342
{
342
{
343
	int i, pos;
343
	int i, pos;
344
	PyObject *key, *value;
344
	PyObject *key, *value;
345
        struct pollfd *old_ufds = self->ufds;
345
346
346
	self->ufd_len = PyDict_Size(self->dict);
347
	self->ufd_len = PyDict_Size(self->dict);
347
	PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
348
	PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
348
	if (self->ufds == NULL) {
349
	if (self->ufds == NULL) {
350
                self->ufds = old_ufds;
349
		PyErr_NoMemory();
351
		PyErr_NoMemory();
350
		return 0;
352
		return 0;
351
	}
353
	}

Return to bug 232137