/[packages]/cauldron/xbmc/current/SOURCES/0007-fixed-CVE-2008-3142-in-internal-python-Gentoo.patch
ViewVC logotype

Contents of /cauldron/xbmc/current/SOURCES/0007-fixed-CVE-2008-3142-in-internal-python-Gentoo.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 78010 - (show annotations) (download)
Sun Mar 27 11:44:10 2011 UTC (13 years ago) by ennael
File size: 8108 byte(s)
imported package xbmc
1 From 448138f1a976bd6311a5eefb34e5e9e6f102b83a Mon Sep 17 00:00:00 2001
2 From: Anssi Hannula <anssi.hannula@iki.fi>
3 Date: Sat, 13 Nov 2010 08:25:46 +0200
4 Subject: [PATCH 07/15] fixed: CVE-2008-3142 in internal python (Gentoo)
5
6 ---
7 xbmc/lib/libPython/Python/Include/pymem.h | 33 ++++++++++++++-------
8 xbmc/lib/libPython/Python/Misc/NEWS | 7 ++++
9 xbmc/lib/libPython/Python/Modules/almodule.c | 2 +
10 xbmc/lib/libPython/Python/Modules/arraymodule.c | 8 +++--
11 xbmc/lib/libPython/Python/Modules/selectmodule.c | 4 ++-
12 xbmc/lib/libPython/Python/Objects/obmalloc.c | 18 ++++++++++++
13 6 files changed, 57 insertions(+), 15 deletions(-)
14
15 diff --git a/xbmc/lib/libPython/Python/Include/pymem.h b/xbmc/lib/libPython/Python/Include/pymem.h
16 index 0e18f03..a3eb095 100644
17 --- a/xbmc/lib/libPython/Python/Include/pymem.h
18 +++ b/xbmc/lib/libPython/Python/Include/pymem.h
19 @@ -66,8 +66,12 @@ PyAPI_FUNC(void) PyMem_Free(void *);
20 for malloc(0), which would be treated as an error. Some platforms
21 would return a pointer with no memory behind it, which would break
22 pymalloc. To solve these problems, allocate an extra byte. */
23 -#define PyMem_MALLOC(n) malloc((n) ? (n) : 1)
24 -#define PyMem_REALLOC(p, n) realloc((p), (n) ? (n) : 1)
25 +/* Returns NULL to indicate error if a negative size or size larger than
26 + Py_ssize_t can represent is supplied. Helps prevents security holes. */
27 +#define PyMem_MALLOC(n) (((n) < 0 || (n) > INT_MAX) ? NULL \
28 + : malloc((n) ? (n) : 1))
29 +#define PyMem_REALLOC(p, n) (((n) < 0 || (n) > INT_MAX) ? NULL \
30 + : realloc((p), (n) ? (n) : 1))
31
32 #endif /* PYMALLOC_DEBUG */
33
34 @@ -80,24 +84,31 @@ PyAPI_FUNC(void) PyMem_Free(void *);
35 * Type-oriented memory interface
36 * ==============================
37 *
38 - * These are carried along for historical reasons. There's rarely a good
39 - * reason to use them anymore (you can just as easily do the multiply and
40 - * cast yourself).
41 + * Allocate memory for n objects of the given type. Returns a new pointer
42 + * or NULL if the request was too large or memory allocation failed. Use
43 + * these macros rather than doing the multiplication yourself so that proper
44 + * overflow checking is always done.
45 */
46
47 #define PyMem_New(type, n) \
48 - ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
49 + ( ((n) > INT_MAX / sizeof(type)) ? NULL : \
50 ( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
51 #define PyMem_NEW(type, n) \
52 - ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
53 + ( ((n) > INT_MAX / sizeof(type)) ? NULL : \
54 ( (type *) PyMem_MALLOC((n) * sizeof(type)) ) )
55
56 +/*
57 + * The value of (p) is always clobbered by this macro regardless of success.
58 + * The caller MUST check if (p) is NULL afterwards and deal with the memory
59 + * error if so. This means the original value of (p) MUST be saved for the
60 + * caller's memory error handler to not lose track of it.
61 + */
62 #define PyMem_Resize(p, type, n) \
63 - ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
64 - ( (p) = (type *) PyMem_Realloc((p), (n) * sizeof(type)) ) )
65 + ( (p) = ((n) > INT_MAX / sizeof(type)) ? NULL : \
66 + (type *) PyMem_Realloc((p), (n) * sizeof(type)) )
67 #define PyMem_RESIZE(p, type, n) \
68 - ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
69 - ( (p) = (type *) PyMem_REALLOC((p), (n) * sizeof(type)) ) )
70 + ( (p) = ((n) > INT_MAX / sizeof(type)) ? NULL : \
71 + (type *) PyMem_REALLOC((p), (n) * sizeof(type)) )
72
73 /* In order to avoid breaking old code mixing PyObject_{New, NEW} with
74 PyMem_{Del, DEL} and PyMem_{Free, FREE}, the PyMem "release memory"
75 diff --git a/xbmc/lib/libPython/Python/Misc/NEWS b/xbmc/lib/libPython/Python/Misc/NEWS
76 index 1c33e2c..39fa7be 100644
77 --- a/xbmc/lib/libPython/Python/Misc/NEWS
78 +++ b/xbmc/lib/libPython/Python/Misc/NEWS
79 @@ -18,6 +18,13 @@ What's New in Python 2.4.5c1?
80 Core and builtins
81 -----------------
82
83 +- Issue #2620: Overflow checking when allocating or reallocating memory
84 + was not always being done properly in some python types and extension
85 + modules. PyMem_MALLOC, PyMem_REALLOC, PyMem_NEW and PyMem_RESIZE have
86 + all been updated to perform better checks and places in the code that
87 + would previously leak memory on the error path when such an allocation
88 + failed have been fixed.
89 +
90 - Added checks for integer overflows, contributed by Google. Some are
91 only available if asserts are left in the code, in cases where they
92 can't be triggered from Python code.
93 diff --git a/xbmc/lib/libPython/Python/Modules/almodule.c b/xbmc/lib/libPython/Python/Modules/almodule.c
94 index fbeb13a..20f26d0 100644
95 --- a/xbmc/lib/libPython/Python/Modules/almodule.c
96 +++ b/xbmc/lib/libPython/Python/Modules/almodule.c
97 @@ -1633,9 +1633,11 @@ al_QueryValues(PyObject *self, PyObject *args)
98 if (nvals < 0)
99 goto cleanup;
100 if (nvals > setsize) {
101 + ALvalue *old_return_set = return_set;
102 setsize = nvals;
103 PyMem_RESIZE(return_set, ALvalue, setsize);
104 if (return_set == NULL) {
105 + return_set = old_return_set;
106 PyErr_NoMemory();
107 goto cleanup;
108 }
109 diff --git a/xbmc/lib/libPython/Python/Modules/arraymodule.c b/xbmc/lib/libPython/Python/Modules/arraymodule.c
110 index aea4773..f7ad5be 100644
111 --- a/xbmc/lib/libPython/Python/Modules/arraymodule.c
112 +++ b/xbmc/lib/libPython/Python/Modules/arraymodule.c
113 @@ -814,6 +814,7 @@ static int
114 array_do_extend(arrayobject *self, PyObject *bb)
115 {
116 int size;
117 + char *old_item;
118
119 if (!array_Check(bb))
120 return array_iter_extend(self, bb);
121 @@ -829,10 +830,11 @@ array_do_extend(arrayobject *self, PyObject *bb)
122 return -1;
123 }
124 size = self->ob_size + b->ob_size;
125 + old_item = self->ob_item;
126 PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize);
127 if (self->ob_item == NULL) {
128 - PyObject_Del(self);
129 - PyErr_NoMemory();
130 + self->ob_item = old_item;
131 + PyErr_NoMemory();
132 return -1;
133 }
134 memcpy(self->ob_item + self->ob_size*self->ob_descr->itemsize,
135 @@ -884,7 +886,7 @@ array_inplace_repeat(arrayobject *self, int n)
136 if (size > INT_MAX / n) {
137 return PyErr_NoMemory();
138 }
139 - PyMem_Resize(items, char, n * size);
140 + PyMem_RESIZE(items, char, n * size);
141 if (items == NULL)
142 return PyErr_NoMemory();
143 p = items;
144 diff --git a/xbmc/lib/libPython/Python/Modules/selectmodule.c b/xbmc/lib/libPython/Python/Modules/selectmodule.c
145 index 53c68c1..25e2310 100644
146 --- a/xbmc/lib/libPython/Python/Modules/selectmodule.c
147 +++ b/xbmc/lib/libPython/Python/Modules/selectmodule.c
148 @@ -342,10 +342,12 @@ update_ufd_array(pollObject *self)
149 {
150 int i, pos;
151 PyObject *key, *value;
152 + struct pollfd *old_ufds = self->ufds;
153
154 self->ufd_len = PyDict_Size(self->dict);
155 - PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
156 + PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
157 if (self->ufds == NULL) {
158 + self->ufds = old_ufds;
159 PyErr_NoMemory();
160 return 0;
161 }
162 diff --git a/xbmc/lib/libPython/Python/Objects/obmalloc.c b/xbmc/lib/libPython/Python/Objects/obmalloc.c
163 index a6fdf40..163c126 100644
164 --- a/xbmc/lib/libPython/Python/Objects/obmalloc.c
165 +++ b/xbmc/lib/libPython/Python/Objects/obmalloc.c
166 @@ -585,6 +585,15 @@ PyObject_Malloc(size_t nbytes)
167 uint size;
168
169 /*
170 + * Limit ourselves to INT_MAX bytes to prevent security holes.
171 + * Most python internals blindly use a signed Py_ssize_t to track
172 + * things without checking for overflows or negatives.
173 + * As size_t is unsigned, checking for nbytes < 0 is not required.
174 + */
175 + if (nbytes > INT_MAX)
176 + return NULL;
177 +
178 + /*
179 * This implicitly redirects malloc(0).
180 */
181 if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) {
182 @@ -814,6 +823,15 @@ PyObject_Realloc(void *p, size_t nbytes)
183 if (p == NULL)
184 return PyObject_Malloc(nbytes);
185
186 + /*
187 + * Limit ourselves to INT_MAX bytes to prevent security holes.
188 + * Most python internals blindly use a signed Py_ssize_t to track
189 + * things without checking for overflows or negatives.
190 + * As size_t is unsigned, checking for nbytes < 0 is not required.
191 + */
192 + if (nbytes > INT_MAX)
193 + return NULL;
194 +
195 pool = POOL_ADDR(p);
196 if (Py_ADDRESS_IN_RANGE(p, pool)) {
197 /* We're in charge of this block */
198 --
199 1.7.3
200

  ViewVC Help
Powered by ViewVC 1.1.30