Commit 4bb17348 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #17016: Get rid of possible pointer wraparounds and integer overflows

in the re module.  Patch by Nickolai Zeldovich.
parent f756f947
...@@ -1344,6 +1344,7 @@ Milan Zamazal ...@@ -1344,6 +1344,7 @@ Milan Zamazal
Artur Zaprzala Artur Zaprzala
Mike Zarnstorff Mike Zarnstorff
Siebren van der Zee Siebren van der Zee
Nickolai Zeldovich
Yuxiao Zeng Yuxiao Zeng
Uwe Zessin Uwe Zessin
Cheng Zhang Cheng Zhang
......
...@@ -29,6 +29,9 @@ Core and Builtins ...@@ -29,6 +29,9 @@ Core and Builtins
Library Library
------- -------
- Issue #17016: Get rid of possible pointer wraparounds and integer overflows
in the re module. Patch by Nickolai Zeldovich.
- Issue #16658: add missing return to HTTPConnection.send() - Issue #16658: add missing return to HTTPConnection.send()
Patch by Jeff Knupp. Patch by Jeff Knupp.
......
...@@ -655,7 +655,7 @@ do { \ ...@@ -655,7 +655,7 @@ do { \
alloc_pos = state->data_stack_base; \ alloc_pos = state->data_stack_base; \
TRACE(("allocating %s in %d (%d)\n", \ TRACE(("allocating %s in %d (%d)\n", \
SFY(type), alloc_pos, sizeof(type))); \ SFY(type), alloc_pos, sizeof(type))); \
if (state->data_stack_size < alloc_pos+sizeof(type)) { \ if (sizeof(type) > state->data_stack_size - alloc_pos) { \
int j = data_stack_grow(state, sizeof(type)); \ int j = data_stack_grow(state, sizeof(type)); \
if (j < 0) return j; \ if (j < 0) return j; \
if (ctx_pos != -1) \ if (ctx_pos != -1) \
...@@ -675,7 +675,7 @@ do { \ ...@@ -675,7 +675,7 @@ do { \
do { \ do { \
TRACE(("copy data in %p to %d (%d)\n", \ TRACE(("copy data in %p to %d (%d)\n", \
data, state->data_stack_base, size)); \ data, state->data_stack_base, size)); \
if (state->data_stack_size < state->data_stack_base+size) { \ if (size > state->data_stack_size - state->data_stack_base) { \
int j = data_stack_grow(state, size); \ int j = data_stack_grow(state, size); \
if (j < 0) return j; \ if (j < 0) return j; \
if (ctx_pos != -1) \ if (ctx_pos != -1) \
...@@ -997,7 +997,7 @@ entrance: ...@@ -997,7 +997,7 @@ entrance:
TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr, TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
ctx->pattern[1], ctx->pattern[2])); ctx->pattern[1], ctx->pattern[2]));
if (ctx->ptr + state->charsize * ctx->pattern[1] > end) if (ctx->pattern[1] > (end - ctx->ptr) / state->charsize)
RETURN_FAILURE; /* cannot match */ RETURN_FAILURE; /* cannot match */
state->ptr = ctx->ptr; state->ptr = ctx->ptr;
...@@ -1081,7 +1081,7 @@ entrance: ...@@ -1081,7 +1081,7 @@ entrance:
TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr, TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
ctx->pattern[1], ctx->pattern[2])); ctx->pattern[1], ctx->pattern[2]));
if (ctx->ptr + state->charsize * ctx->pattern[1] > end) if (ctx->pattern[1] > (end - ctx->ptr) / state->charsize)
RETURN_FAILURE; /* cannot match */ RETURN_FAILURE; /* cannot match */
state->ptr = ctx->ptr; state->ptr = ctx->ptr;
...@@ -2779,7 +2779,7 @@ _compile(PyObject* self_, PyObject* args) ...@@ -2779,7 +2779,7 @@ _compile(PyObject* self_, PyObject* args)
skip = *code; \ skip = *code; \
VTRACE(("%lu (skip to %p)\n", \ VTRACE(("%lu (skip to %p)\n", \
(unsigned long)skip, code+skip)); \ (unsigned long)skip, code+skip)); \
if (code+skip-adj < code || code+skip-adj > end)\ if (skip-adj > end-code) \
FAIL; \ FAIL; \
code++; \ code++; \
} while (0) } while (0)
...@@ -2812,7 +2812,7 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end) ...@@ -2812,7 +2812,7 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end)
case SRE_OP_CHARSET: case SRE_OP_CHARSET:
offset = 32/sizeof(SRE_CODE); /* 32-byte bitmap */ offset = 32/sizeof(SRE_CODE); /* 32-byte bitmap */
if (code+offset < code || code+offset > end) if (offset > end-code)
FAIL; FAIL;
code += offset; code += offset;
break; break;
...@@ -2820,7 +2820,7 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end) ...@@ -2820,7 +2820,7 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end)
case SRE_OP_BIGCHARSET: case SRE_OP_BIGCHARSET:
GET_ARG; /* Number of blocks */ GET_ARG; /* Number of blocks */
offset = 256/sizeof(SRE_CODE); /* 256-byte table */ offset = 256/sizeof(SRE_CODE); /* 256-byte table */
if (code+offset < code || code+offset > end) if (offset > end-code)
FAIL; FAIL;
/* Make sure that each byte points to a valid block */ /* Make sure that each byte points to a valid block */
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
...@@ -2829,7 +2829,7 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end) ...@@ -2829,7 +2829,7 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end)
} }
code += offset; code += offset;
offset = arg * 32/sizeof(SRE_CODE); /* 32-byte bitmap times arg */ offset = arg * 32/sizeof(SRE_CODE); /* 32-byte bitmap times arg */
if (code+offset < code || code+offset > end) if (offset > end-code)
FAIL; FAIL;
code += offset; code += offset;
break; break;
...@@ -2980,11 +2980,11 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) ...@@ -2980,11 +2980,11 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups)
GET_ARG; prefix_len = arg; GET_ARG; prefix_len = arg;
GET_ARG; GET_ARG;
/* Here comes the prefix string */ /* Here comes the prefix string */
if (code+prefix_len < code || code+prefix_len > newcode) if (prefix_len > newcode-code)
FAIL; FAIL;
code += prefix_len; code += prefix_len;
/* And here comes the overlap table */ /* And here comes the overlap table */
if (code+prefix_len < code || code+prefix_len > newcode) if (prefix_len > newcode-code)
FAIL; FAIL;
/* Each overlap value should be < prefix_len */ /* Each overlap value should be < prefix_len */
for (i = 0; i < prefix_len; i++) { for (i = 0; i < prefix_len; i++) {
...@@ -3113,7 +3113,7 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) ...@@ -3113,7 +3113,7 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups)
to allow arbitrary jumps anywhere in the code; so we just look to allow arbitrary jumps anywhere in the code; so we just look
for a JUMP opcode preceding our skip target. for a JUMP opcode preceding our skip target.
*/ */
if (skip >= 3 && code+skip-3 >= code && if (skip >= 3 && skip-3 < end-code &&
code[skip-3] == SRE_OP_JUMP) code[skip-3] == SRE_OP_JUMP)
{ {
VTRACE(("both then and else parts present\n")); VTRACE(("both then and else parts present\n"));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment