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

in the re module.  Patch by Nickolai Zeldovich.
This commit is contained in:
Serhiy Storchaka 2013-04-13 21:15:47 +03:00
parent f756f947f9
commit 4bb17348f5
3 changed files with 15 additions and 11 deletions

View file

@ -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

View file

@ -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.

View file

@ -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 { \
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:
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:
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)
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)
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)
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)
} }
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)
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)
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"));