]>
Commit | Line | Data |
---|---|---|
9f8847fe AM |
1 | commit 4ec9f64e07c8f397ad6699f8b99843846c219588 |
2 | Author: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | |
3 | Date: Fri Oct 19 16:14:42 2018 -0700 | |
4 | ||
5 | bpo-34824: Fix a possible NULL pointer dereference in _ssl.c (GH-9606) (GH-9743) | |
6 | ||
7 | On failure, _PyBytes_Resize() will deallocate the bytes object and set | |
8 | "result" to NULL. | |
9 | ||
10 | https://bugs.python.org/issue34824 | |
11 | (cherry picked from commit 365ad2ead5bbaf7a3b18648ffa36e819559d3f75) | |
12 | ||
13 | Co-authored-by: Zackery Spytz <zspytz@gmail.com> | |
14 | ||
15 | diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-09-27-11-10-02.bpo-34824.VLlCaU.rst b/Misc/NEWS.d/next/Core and Builtins/2018-09-27-11-10-02.bpo-34824.VLlCaU.rst | |
16 | new file mode 100644 | |
17 | index 0000000000..fe95b8973c | |
18 | --- /dev/null | |
19 | +++ b/Misc/NEWS.d/next/Core and Builtins/2018-09-27-11-10-02.bpo-34824.VLlCaU.rst | |
20 | @@ -0,0 +1,2 @@ | |
21 | +Fix a possible null pointer dereference in Modules/_ssl.c. Patch by Zackery | |
22 | +Spytz. | |
23 | diff --git a/Modules/_ssl.c b/Modules/_ssl.c | |
24 | index 4253e2a772..f9d1b8c308 100644 | |
25 | --- a/Modules/_ssl.c | |
26 | +++ b/Modules/_ssl.c | |
27 | @@ -4711,12 +4711,17 @@ _ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len) | |
28 | return result; | |
29 | ||
30 | nbytes = BIO_read(self->bio, PyBytes_AS_STRING(result), len); | |
31 | - /* There should never be any short reads but check anyway. */ | |
32 | - if ((nbytes < len) && (_PyBytes_Resize(&result, len) < 0)) { | |
33 | + if (nbytes < 0) { | |
34 | Py_DECREF(result); | |
35 | + _setSSLError(NULL, 0, __FILE__, __LINE__); | |
36 | return NULL; | |
37 | } | |
38 | ||
39 | + /* There should never be any short reads but check anyway. */ | |
40 | + if (nbytes < len) { | |
41 | + _PyBytes_Resize(&result, nbytes); | |
42 | + } | |
43 | + | |
44 | return result; | |
45 | } | |
46 | ||
47 | commit 7f34d550231e047c88a1817b58bda03a33817490 | |
48 | Author: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | |
49 | Date: Sun Oct 21 05:55:52 2018 -0700 | |
50 | ||
51 | bpo-34973: Fix crash in bytes constructor. (GH-9841) | |
52 | ||
53 | ||
54 | Constructing bytes from mutating list could cause a crash. | |
55 | (cherry picked from commit 914f9a078f997e58cfcfabcbb30fafdd1f277bef) | |
56 | ||
57 | Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> | |
58 | ||
59 | diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py | |
60 | index b9c5b628c4..145411efbb 100644 | |
61 | --- a/Lib/test/test_bytes.py | |
62 | +++ b/Lib/test/test_bytes.py | |
63 | @@ -113,6 +113,23 @@ class BaseBytesTest: | |
64 | b = self.type2test([1, 2, 3]) | |
65 | self.assertEqual(b, b"\x01\x02\x03") | |
66 | ||
67 | + def test_from_mutating_list(self): | |
68 | + # Issue #34973: Crash in bytes constructor with mutating list. | |
69 | + class X: | |
70 | + def __index__(self): | |
71 | + a.clear() | |
72 | + return 42 | |
73 | + a = [X(), X()] | |
74 | + self.assertEqual(bytes(a), b'*') | |
75 | + | |
76 | + class Y: | |
77 | + def __index__(self): | |
78 | + if len(a) < 1000: | |
79 | + a.append(self) | |
80 | + return 42 | |
81 | + a = [Y()] | |
82 | + self.assertEqual(bytes(a), b'*' * 1000) # should not crash | |
83 | + | |
84 | def test_from_index(self): | |
85 | b = self.type2test([Indexable(), Indexable(1), Indexable(254), | |
86 | Indexable(255)]) | |
87 | diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-10-13-16-42-03.bpo-34973.B5M-3g.rst b/Misc/NEWS.d/next/Core and Builtins/2018-10-13-16-42-03.bpo-34973.B5M-3g.rst | |
88 | new file mode 100644 | |
89 | index 0000000000..6e403cd4ce | |
90 | --- /dev/null | |
91 | +++ b/Misc/NEWS.d/next/Core and Builtins/2018-10-13-16-42-03.bpo-34973.B5M-3g.rst | |
92 | @@ -0,0 +1,2 @@ | |
93 | +Fixed crash in :func:`bytes` when the :class:`list` argument is mutated | |
94 | +while it is iterated. | |
95 | diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c | |
96 | index 5b62842093..711faba645 100644 | |
97 | --- a/Objects/bytesobject.c | |
98 | +++ b/Objects/bytesobject.c | |
99 | @@ -2640,49 +2640,83 @@ fail: | |
100 | return NULL; | |
101 | } | |
102 | ||
103 | -#define _PyBytes_FROM_LIST_BODY(x, GET_ITEM) \ | |
104 | - do { \ | |
105 | - PyObject *bytes; \ | |
106 | - Py_ssize_t i; \ | |
107 | - Py_ssize_t value; \ | |
108 | - char *str; \ | |
109 | - PyObject *item; \ | |
110 | - \ | |
111 | - bytes = PyBytes_FromStringAndSize(NULL, Py_SIZE(x)); \ | |
112 | - if (bytes == NULL) \ | |
113 | - return NULL; \ | |
114 | - str = ((PyBytesObject *)bytes)->ob_sval; \ | |
115 | - \ | |
116 | - for (i = 0; i < Py_SIZE(x); i++) { \ | |
117 | - item = GET_ITEM((x), i); \ | |
118 | - value = PyNumber_AsSsize_t(item, NULL); \ | |
119 | - if (value == -1 && PyErr_Occurred()) \ | |
120 | - goto error; \ | |
121 | - \ | |
122 | - if (value < 0 || value >= 256) { \ | |
123 | - PyErr_SetString(PyExc_ValueError, \ | |
124 | - "bytes must be in range(0, 256)"); \ | |
125 | - goto error; \ | |
126 | - } \ | |
127 | - *str++ = (char) value; \ | |
128 | - } \ | |
129 | - return bytes; \ | |
130 | - \ | |
131 | - error: \ | |
132 | - Py_DECREF(bytes); \ | |
133 | - return NULL; \ | |
134 | - } while (0) | |
135 | - | |
136 | static PyObject* | |
137 | _PyBytes_FromList(PyObject *x) | |
138 | { | |
139 | - _PyBytes_FROM_LIST_BODY(x, PyList_GET_ITEM); | |
140 | + Py_ssize_t i, size = PyList_GET_SIZE(x); | |
141 | + Py_ssize_t value; | |
142 | + char *str; | |
143 | + PyObject *item; | |
144 | + _PyBytesWriter writer; | |
145 | + | |
146 | + _PyBytesWriter_Init(&writer); | |
147 | + str = _PyBytesWriter_Alloc(&writer, size); | |
148 | + if (str == NULL) | |
149 | + return NULL; | |
150 | + writer.overallocate = 1; | |
151 | + size = writer.allocated; | |
152 | + | |
153 | + for (i = 0; i < PyList_GET_SIZE(x); i++) { | |
154 | + item = PyList_GET_ITEM(x, i); | |
155 | + Py_INCREF(item); | |
156 | + value = PyNumber_AsSsize_t(item, NULL); | |
157 | + Py_DECREF(item); | |
158 | + if (value == -1 && PyErr_Occurred()) | |
159 | + goto error; | |
160 | + | |
161 | + if (value < 0 || value >= 256) { | |
162 | + PyErr_SetString(PyExc_ValueError, | |
163 | + "bytes must be in range(0, 256)"); | |
164 | + goto error; | |
165 | + } | |
166 | + | |
167 | + if (i >= size) { | |
168 | + str = _PyBytesWriter_Resize(&writer, str, size+1); | |
169 | + if (str == NULL) | |
170 | + return NULL; | |
171 | + size = writer.allocated; | |
172 | + } | |
173 | + *str++ = (char) value; | |
174 | + } | |
175 | + return _PyBytesWriter_Finish(&writer, str); | |
176 | + | |
177 | + error: | |
178 | + _PyBytesWriter_Dealloc(&writer); | |
179 | + return NULL; | |
180 | } | |
181 | ||
182 | static PyObject* | |
183 | _PyBytes_FromTuple(PyObject *x) | |
184 | { | |
185 | - _PyBytes_FROM_LIST_BODY(x, PyTuple_GET_ITEM); | |
186 | + PyObject *bytes; | |
187 | + Py_ssize_t i, size = PyTuple_GET_SIZE(x); | |
188 | + Py_ssize_t value; | |
189 | + char *str; | |
190 | + PyObject *item; | |
191 | + | |
192 | + bytes = PyBytes_FromStringAndSize(NULL, size); | |
193 | + if (bytes == NULL) | |
194 | + return NULL; | |
195 | + str = ((PyBytesObject *)bytes)->ob_sval; | |
196 | + | |
197 | + for (i = 0; i < size; i++) { | |
198 | + item = PyTuple_GET_ITEM(x, i); | |
199 | + value = PyNumber_AsSsize_t(item, NULL); | |
200 | + if (value == -1 && PyErr_Occurred()) | |
201 | + goto error; | |
202 | + | |
203 | + if (value < 0 || value >= 256) { | |
204 | + PyErr_SetString(PyExc_ValueError, | |
205 | + "bytes must be in range(0, 256)"); | |
206 | + goto error; | |
207 | + } | |
208 | + *str++ = (char) value; | |
209 | + } | |
210 | + return bytes; | |
211 | + | |
212 | + error: | |
213 | + Py_DECREF(bytes); | |
214 | + return NULL; | |
215 | } | |
216 | ||
217 | static PyObject * | |
218 | commit c46f0423a42c46cf62d12c300ec36a848f8ba72c | |
219 | Author: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | |
220 | Date: Tue Oct 23 12:45:44 2018 -0700 | |
221 | ||
222 | Fix error handling bugs in _elementtree.c. (GH-10060) | |
223 | ||
224 | ||
225 | References could leak, NULL could be dereferenced, and the Expat parser could | |
226 | be double freed when some errors raised. | |
227 | (cherry picked from commit 9f3ed3e213b30059087d059a7d1d3b2527fa8654) | |
228 | ||
229 | Co-authored-by: Zackery Spytz <zspytz@gmail.com> | |
230 | ||
231 | diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c | |
232 | index d13c6dd4db..3118b55c87 100644 | |
233 | --- a/Modules/_elementtree.c | |
234 | +++ b/Modules/_elementtree.c | |
235 | @@ -336,6 +336,9 @@ static PyObject* | |
236 | get_attrib_from_keywords(PyObject *kwds) | |
237 | { | |
238 | PyObject *attrib_str = PyUnicode_FromString("attrib"); | |
239 | + if (attrib_str == NULL) { | |
240 | + return NULL; | |
241 | + } | |
242 | PyObject *attrib = PyDict_GetItem(kwds, attrib_str); | |
243 | ||
244 | if (attrib) { | |
245 | @@ -356,10 +359,10 @@ get_attrib_from_keywords(PyObject *kwds) | |
246 | ||
247 | Py_DECREF(attrib_str); | |
248 | ||
249 | - /* attrib can be NULL if PyDict_New failed */ | |
250 | - if (attrib) | |
251 | - if (PyDict_Update(attrib, kwds) < 0) | |
252 | - return NULL; | |
253 | + if (attrib != NULL && PyDict_Update(attrib, kwds) < 0) { | |
254 | + Py_DECREF(attrib); | |
255 | + return NULL; | |
256 | + } | |
257 | return attrib; | |
258 | } | |
259 | ||
260 | @@ -579,10 +582,9 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds) | |
261 | attrib = PyDict_Copy(attrib); | |
262 | if (!attrib) | |
263 | return NULL; | |
264 | - if (kwds) { | |
265 | - if (PyDict_Update(attrib, kwds) < 0) { | |
266 | - return NULL; | |
267 | - } | |
268 | + if (kwds != NULL && PyDict_Update(attrib, kwds) < 0) { | |
269 | + Py_DECREF(attrib); | |
270 | + return NULL; | |
271 | } | |
272 | } else if (kwds) { | |
273 | /* have keyword args */ | |
274 | @@ -1857,7 +1859,6 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) | |
275 | * scheduled for removal. | |
276 | */ | |
277 | if (!(recycle = PyList_New(slicelen))) { | |
278 | - PyErr_NoMemory(); | |
279 | return -1; | |
280 | } | |
281 | ||
282 | @@ -1897,7 +1898,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) | |
283 | self->extra->length -= slicelen; | |
284 | ||
285 | /* Discard the recycle list with all the deleted sub-elements */ | |
286 | - Py_XDECREF(recycle); | |
287 | + Py_DECREF(recycle); | |
288 | return 0; | |
289 | } | |
290 | ||
291 | @@ -3352,7 +3353,6 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *html, | |
292 | if (!target) { | |
293 | Py_CLEAR(self->entity); | |
294 | Py_CLEAR(self->names); | |
295 | - EXPAT(ParserFree)(self->parser); | |
296 | return -1; | |
297 | } | |
298 | } | |
299 | commit da15389fddb85cf8a97b81e75de7d77b5f505b56 | |
300 | Author: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | |
301 | Date: Wed Oct 31 02:31:29 2018 -0700 | |
302 | ||
303 | Fix a possible crash in range.__reversed__(). (GH-10252) | |
304 | ||
305 | (cherry picked from commit c9a6168924ffa4f3f78175998b392fe23d3edc50) | |
306 | ||
307 | Co-authored-by: Zackery Spytz <zspytz@gmail.com> | |
308 | ||
309 | diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c | |
310 | index e4f778b1f8..037be870e3 100644 | |
311 | --- a/Objects/rangeobject.c | |
312 | +++ b/Objects/rangeobject.c | |
313 | @@ -1154,6 +1154,7 @@ long_range: | |
314 | it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); | |
315 | if (it == NULL) | |
316 | return NULL; | |
317 | + it->index = it->start = it->step = NULL; | |
318 | ||
319 | /* start + (len - 1) * step */ | |
320 | it->len = range->length; | |
321 | commit 192c54713b4c67a8d14b2d98056771feba40ca37 | |
322 | Author: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | |
323 | Date: Wed Oct 31 16:45:42 2018 -0700 | |
324 | ||
325 | bpo-26558: Fix Py_FatalError() with GIL released (GH-10267) | |
326 | ||
327 | ||
328 | Don't call _Py_FatalError_PrintExc() nor flush_std_files() if the | |
329 | current thread doesn't hold the GIL, or if the current thread | |
330 | has no Python state thread. | |
331 | (cherry picked from commit 3a228ab17c2a9cffd1a2f15f30d6209768de20a6) | |
332 | ||
333 | Co-authored-by: Victor Stinner <vstinner@redhat.com> | |
334 | ||
335 | diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c | |
336 | index c01b21ffeb..86f95de833 100644 | |
337 | --- a/Python/pylifecycle.c | |
338 | +++ b/Python/pylifecycle.c | |
339 | @@ -2015,12 +2015,6 @@ _Py_FatalError_PrintExc(int fd) | |
340 | PyObject *exception, *v, *tb; | |
341 | int has_tb; | |
342 | ||
343 | - if (PyThreadState_GET() == NULL) { | |
344 | - /* The GIL is released: trying to acquire it is likely to deadlock, | |
345 | - just give up. */ | |
346 | - return 0; | |
347 | - } | |
348 | - | |
349 | PyErr_Fetch(&exception, &v, &tb); | |
350 | if (exception == NULL) { | |
351 | /* No current exception */ | |
352 | @@ -2125,9 +2119,30 @@ fatal_error(const char *prefix, const char *msg, int status) | |
353 | fputs("\n", stderr); | |
354 | fflush(stderr); /* it helps in Windows debug build */ | |
355 | ||
356 | - /* Print the exception (if an exception is set) with its traceback, | |
357 | - * or display the current Python stack. */ | |
358 | - if (!_Py_FatalError_PrintExc(fd)) { | |
359 | + /* Check if the current thread has a Python thread state | |
360 | + and holds the GIL */ | |
361 | + PyThreadState *tss_tstate = PyGILState_GetThisThreadState(); | |
362 | + if (tss_tstate != NULL) { | |
363 | + PyThreadState *tstate = PyThreadState_GET(); | |
364 | + if (tss_tstate != tstate) { | |
365 | + /* The Python thread does not hold the GIL */ | |
366 | + tss_tstate = NULL; | |
367 | + } | |
368 | + } | |
369 | + else { | |
370 | + /* Py_FatalError() has been called from a C thread | |
371 | + which has no Python thread state. */ | |
372 | + } | |
373 | + int has_tstate_and_gil = (tss_tstate != NULL); | |
374 | + | |
375 | + if (has_tstate_and_gil) { | |
376 | + /* If an exception is set, print the exception with its traceback */ | |
377 | + if (!_Py_FatalError_PrintExc(fd)) { | |
378 | + /* No exception is set, or an exception is set without traceback */ | |
379 | + _Py_FatalError_DumpTracebacks(fd); | |
380 | + } | |
381 | + } | |
382 | + else { | |
383 | _Py_FatalError_DumpTracebacks(fd); | |
384 | } | |
385 | ||
386 | @@ -2138,7 +2153,7 @@ fatal_error(const char *prefix, const char *msg, int status) | |
387 | _PyFaulthandler_Fini(); | |
388 | ||
389 | /* Check if the current Python thread hold the GIL */ | |
390 | - if (PyThreadState_GET() != NULL) { | |
391 | + if (has_tstate_and_gil) { | |
392 | /* Flush sys.stdout and sys.stderr */ | |
393 | flush_std_files(); | |
394 | } | |
395 | commit f16ebcd460aaeb8d6b31db317d22f5ed68afbcc8 | |
396 | Author: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | |
397 | Date: Thu Nov 8 18:13:14 2018 -0800 | |
398 | ||
399 | bpo-35193: Fix an off by one error in the RETURN_VALUE case. (GH-10418) | |
400 | ||
401 | ||
402 | Fix an off by one error in the peephole optimizer when checking for unreachable code beyond a return. | |
403 | ||
404 | Do a bounds check within find_op so it can return before going past the end as a safety measure. | |
405 | ||
406 | https://github.com/python/cpython/commit/7db3c488335168993689ddae5914a28e16188447GH-diff-a33329ae6ae0bb295d742f0caf93c137 | |
407 | introduced this off by one error while fixing another one nearby. | |
408 | ||
409 | This bug was shipped in all Python 3.6 and 3.7 releases. | |
410 | ||
411 | The included unittest won't fail unless you do a clang msan build. | |
412 | (cherry picked from commit 49fa4a9f1ef387e16596f271414c855339eadf09) | |
413 | ||
414 | Co-authored-by: Gregory P. Smith <greg@krypto.org> | |
415 | ||
416 | diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py | |
417 | index d8a57e5e09..5ac1c5f271 100644 | |
418 | --- a/Lib/test/test_compile.py | |
419 | +++ b/Lib/test/test_compile.py | |
420 | @@ -1,3 +1,4 @@ | |
421 | +import dis | |
422 | import math | |
423 | import os | |
424 | import unittest | |
425 | @@ -621,6 +622,24 @@ if 1: | |
426 | self.check_constant(f1, frozenset({0})) | |
427 | self.assertTrue(f1(0)) | |
428 | ||
429 | + # This is a regression test for a CPython specific peephole optimizer | |
430 | + # implementation bug present in a few releases. It's assertion verifies | |
431 | + # that peephole optimization was actually done though that isn't an | |
432 | + # indication of the bugs presence or not (crashing is). | |
433 | + @support.cpython_only | |
434 | + def test_peephole_opt_unreachable_code_array_access_in_bounds(self): | |
435 | + """Regression test for issue35193 when run under clang msan.""" | |
436 | + def unused_code_at_end(): | |
437 | + return 3 | |
438 | + raise RuntimeError("unreachable") | |
439 | + # The above function definition will trigger the out of bounds | |
440 | + # bug in the peephole optimizer as it scans opcodes past the | |
441 | + # RETURN_VALUE opcode. This does not always crash an interpreter. | |
442 | + # When you build with the clang memory sanitizer it reliably aborts. | |
443 | + self.assertEqual( | |
444 | + 'RETURN_VALUE', | |
445 | + list(dis.get_instructions(unused_code_at_end))[-1].opname) | |
446 | + | |
447 | def test_dont_merge_constants(self): | |
448 | # Issue #25843: compile() must not merge constants which are equal | |
449 | # but have a different type. | |
450 | diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-11-08-15-00-58.bpo-35193.HzPS6R.rst b/Misc/NEWS.d/next/Core and Builtins/2018-11-08-15-00-58.bpo-35193.HzPS6R.rst | |
451 | new file mode 100644 | |
452 | index 0000000000..dddebe1670 | |
453 | --- /dev/null | |
454 | +++ b/Misc/NEWS.d/next/Core and Builtins/2018-11-08-15-00-58.bpo-35193.HzPS6R.rst | |
455 | @@ -0,0 +1,3 @@ | |
456 | +Fix an off by one error in the bytecode peephole optimizer where it could read | |
457 | +bytes beyond the end of bounds of an array when removing unreachable code. | |
458 | +This bug was present in every release of Python 3.6 and 3.7 until now. | |
459 | diff --git a/Python/peephole.c b/Python/peephole.c | |
460 | index 76a0edbcc2..a3b078fdf1 100644 | |
461 | --- a/Python/peephole.c | |
462 | +++ b/Python/peephole.c | |
463 | @@ -50,9 +50,9 @@ lastn_const_start(const _Py_CODEUNIT *codestr, Py_ssize_t i, Py_ssize_t n) | |
464 | ||
465 | /* Scans through EXTENDED ARGs, seeking the index of the effective opcode */ | |
466 | static Py_ssize_t | |
467 | -find_op(const _Py_CODEUNIT *codestr, Py_ssize_t i) | |
468 | +find_op(const _Py_CODEUNIT *codestr, Py_ssize_t codelen, Py_ssize_t i) | |
469 | { | |
470 | - while (_Py_OPCODE(codestr[i]) == EXTENDED_ARG) { | |
471 | + while (i < codelen && _Py_OPCODE(codestr[i]) == EXTENDED_ARG) { | |
472 | i++; | |
473 | } | |
474 | return i; | |
475 | @@ -128,8 +128,9 @@ copy_op_arg(_Py_CODEUNIT *codestr, Py_ssize_t i, unsigned char op, | |
476 | Called with codestr pointing to the first LOAD_CONST. | |
477 | */ | |
478 | static Py_ssize_t | |
479 | -fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t c_start, | |
480 | - Py_ssize_t opcode_end, PyObject *consts, int n) | |
481 | +fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t codelen, | |
482 | + Py_ssize_t c_start, Py_ssize_t opcode_end, | |
483 | + PyObject *consts, int n) | |
484 | { | |
485 | /* Pre-conditions */ | |
486 | assert(PyList_CheckExact(consts)); | |
487 | @@ -142,7 +143,7 @@ fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t c_start, | |
488 | ||
489 | for (Py_ssize_t i = 0, pos = c_start; i < n; i++, pos++) { | |
490 | assert(pos < opcode_end); | |
491 | - pos = find_op(codestr, pos); | |
492 | + pos = find_op(codestr, codelen, pos); | |
493 | assert(_Py_OPCODE(codestr[pos]) == LOAD_CONST); | |
494 | ||
495 | unsigned int arg = get_arg(codestr, pos); | |
496 | @@ -267,7 +268,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, | |
497 | goto exitError; | |
498 | assert(PyList_Check(consts)); | |
499 | ||
500 | - for (i=find_op(codestr, 0) ; i<codelen ; i=nexti) { | |
501 | + for (i=find_op(codestr, codelen, 0) ; i<codelen ; i=nexti) { | |
502 | opcode = _Py_OPCODE(codestr[i]); | |
503 | op_start = i; | |
504 | while (op_start >= 1 && _Py_OPCODE(codestr[op_start-1]) == EXTENDED_ARG) { | |
505 | @@ -305,7 +306,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, | |
506 | if (j > 0 && lastlc >= j) { | |
507 | h = lastn_const_start(codestr, op_start, j); | |
508 | if (ISBASICBLOCK(blocks, h, op_start)) { | |
509 | - h = fold_tuple_on_constants(codestr, h, i+1, consts, j); | |
510 | + h = fold_tuple_on_constants(codestr, codelen, | |
511 | + h, i+1, consts, j); | |
512 | break; | |
513 | } | |
514 | } | |
515 | @@ -342,7 +344,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, | |
516 | case JUMP_IF_FALSE_OR_POP: | |
517 | case JUMP_IF_TRUE_OR_POP: | |
518 | h = get_arg(codestr, i) / sizeof(_Py_CODEUNIT); | |
519 | - tgt = find_op(codestr, h); | |
520 | + tgt = find_op(codestr, codelen, h); | |
521 | ||
522 | j = _Py_OPCODE(codestr[tgt]); | |
523 | if (CONDITIONAL_JUMP(j)) { | |
524 | @@ -383,7 +385,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, | |
525 | case SETUP_WITH: | |
526 | case SETUP_ASYNC_WITH: | |
527 | h = GETJUMPTGT(codestr, i); | |
528 | - tgt = find_op(codestr, h); | |
529 | + tgt = find_op(codestr, codelen, h); | |
530 | /* Replace JUMP_* to a RETURN into just a RETURN */ | |
531 | if (UNCONDITIONAL_JUMP(opcode) && | |
532 | _Py_OPCODE(codestr[tgt]) == RETURN_VALUE) { | |
533 | @@ -412,7 +414,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, | |
534 | } | |
535 | if (h > i + 1) { | |
536 | fill_nops(codestr, i + 1, h); | |
537 | - nexti = find_op(codestr, h); | |
538 | + nexti = find_op(codestr, codelen, h); | |
539 | } | |
540 | break; | |
541 | } | |
542 | commit 9fbcb1402efab4e287f25145a69ba14c9c6dbce9 | |
543 | Author: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | |
544 | Date: Tue Nov 13 16:39:36 2018 -0800 | |
545 | ||
546 | [3.7] bpo-35214: Fix OOB memory access in unicode escape parser (GH-10506) (GH-10522) | |
547 | ||
548 | ||
549 | ||
550 | Discovered using clang's MemorySanitizer when it ran python3's | |
551 | test_fstring test_misformed_unicode_character_name. | |
552 | ||
553 | An msan build will fail by simply executing: ./python -c 'u"\N"' | |
554 | (cherry picked from commit 746b2d35ea47005054ed774fecaed64fab803d7d) | |
555 | ||
556 | ||
557 | Co-authored-by: Gregory P. Smith <greg@krypto.org> | |
558 | ||
559 | ||
560 | https://bugs.python.org/issue35214 | |
561 | ||
562 | diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-11-13-00-40-35.bpo-35214.OQBjph.rst b/Misc/NEWS.d/next/Core and Builtins/2018-11-13-00-40-35.bpo-35214.OQBjph.rst | |
563 | new file mode 100644 | |
564 | index 0000000000..d462c97d80 | |
565 | --- /dev/null | |
566 | +++ b/Misc/NEWS.d/next/Core and Builtins/2018-11-13-00-40-35.bpo-35214.OQBjph.rst | |
567 | @@ -0,0 +1,3 @@ | |
568 | +Fixed an out of bounds memory access when parsing a truncated unicode | |
569 | +escape sequence at the end of a string such as ``'\N'``. It would read | |
570 | +one byte beyond the end of the memory allocation. | |
571 | diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c | |
572 | index fe833a76ea..71eb654095 100644 | |
573 | --- a/Objects/unicodeobject.c | |
574 | +++ b/Objects/unicodeobject.c | |
575 | @@ -6042,7 +6042,7 @@ _PyUnicode_DecodeUnicodeEscape(const char *s, | |
576 | } | |
577 | ||
578 | message = "malformed \\N character escape"; | |
579 | - if (*s == '{') { | |
580 | + if (s < end && *s == '{') { | |
581 | const char *start = ++s; | |
582 | size_t namelen; | |
583 | /* look for the closing brace */ | |
584 | commit b5ea5e57f5dd23e1db695dda8bf3f6142ed9074f | |
585 | Author: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | |
586 | Date: Thu Nov 15 01:25:34 2018 -0800 | |
587 | ||
588 | Fix a possible reference leak in _socket.getaddrinfo(). (GH-10543) | |
589 | ||
590 | ||
591 | "single" needs to be decrefed if PyList_Append() fails. | |
592 | (cherry picked from commit 4c596d54aa6a55e9d2a3db78891e656ebbfb63c8) | |
593 | ||
594 | Co-authored-by: Zackery Spytz <zspytz@gmail.com> | |
595 | ||
596 | diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c | |
597 | index eeade2ecad..ddb1c4364b 100644 | |
598 | --- a/Modules/socketmodule.c | |
599 | +++ b/Modules/socketmodule.c | |
600 | @@ -6269,9 +6269,11 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) | |
601 | if (single == NULL) | |
602 | goto err; | |
603 | ||
604 | - if (PyList_Append(all, single)) | |
605 | + if (PyList_Append(all, single)) { | |
606 | + Py_DECREF(single); | |
607 | goto err; | |
608 | - Py_XDECREF(single); | |
609 | + } | |
610 | + Py_DECREF(single); | |
611 | } | |
612 | Py_XDECREF(idna); | |
613 | if (res0) |