From 616f2fe28ca3fdc54e4a04790ed287b845240e6c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 13 Apr 2013 21:15:10 +0300 Subject: Issue #17016: Get rid of possible pointer wraparounds and integer overflows in the re module. Patch by Nickolai Zeldovich. --- Misc/ACKS | 1 + Misc/NEWS | 3 +++ Modules/_sre.c | 22 +++++++++++----------- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Misc/ACKS b/Misc/ACKS index 4de44cc..5779332 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1130,6 +1130,7 @@ Milan Zamazal Artur Zaprzala Mike Zarnstorff Siebren van der Zee +Nickolai Zeldovich Uwe Zessin Cheng Zhang Tarek Ziadé diff --git a/Misc/NEWS b/Misc/NEWS index aea5b13..1dd72fb 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,9 @@ Core and Builtins Library ------- +- Issue #17016: Get rid of possible pointer wraparounds and integer overflows + in the re module. Patch by Nickolai Zeldovich. + - Issue #17536: Add to webbrowser's browser list: xdg-open, gvfs-open, www-browser, x-www-browser, chromium browsers, iceweasel, iceape. diff --git a/Modules/_sre.c b/Modules/_sre.c index f3a2993..478416f 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -686,7 +686,7 @@ do { \ alloc_pos = state->data_stack_base; \ TRACE(("allocating %s in %d (%d)\n", \ 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)); \ if (j < 0) return j; \ if (ctx_pos != -1) \ @@ -706,7 +706,7 @@ do { \ do { \ TRACE(("copy data in %p to %d (%d)\n", \ 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); \ if (j < 0) return j; \ if (ctx_pos != -1) \ @@ -1028,7 +1028,7 @@ entrance: TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr, ctx->pattern[1], ctx->pattern[2])); - if (ctx->ptr + ctx->pattern[1] > end) + if (ctx->pattern[1] > end - ctx->ptr) RETURN_FAILURE; /* cannot match */ state->ptr = ctx->ptr; @@ -1111,7 +1111,7 @@ entrance: TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr, ctx->pattern[1], ctx->pattern[2])); - if (ctx->ptr + ctx->pattern[1] > end) + if (ctx->pattern[1] > end - ctx->ptr) RETURN_FAILURE; /* cannot match */ state->ptr = ctx->ptr; @@ -2784,7 +2784,7 @@ _compile(PyObject* self_, PyObject* args) skip = *code; \ VTRACE(("%lu (skip to %p)\n", \ (unsigned long)skip, code+skip)); \ - if (code+skip-adj < code || code+skip-adj > end)\ + if (skip-adj > end-code) \ FAIL; \ code++; \ } while (0) @@ -2817,7 +2817,7 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end) case SRE_OP_CHARSET: offset = 32/sizeof(SRE_CODE); /* 32-byte bitmap */ - if (code+offset < code || code+offset > end) + if (offset > end-code) FAIL; code += offset; break; @@ -2825,7 +2825,7 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end) case SRE_OP_BIGCHARSET: GET_ARG; /* Number of blocks */ offset = 256/sizeof(SRE_CODE); /* 256-byte table */ - if (code+offset < code || code+offset > end) + if (offset > end-code) FAIL; /* Make sure that each byte points to a valid block */ for (i = 0; i < 256; i++) { @@ -2834,7 +2834,7 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end) } code += offset; offset = arg * 32/sizeof(SRE_CODE); /* 32-byte bitmap times arg */ - if (code+offset < code || code+offset > end) + if (offset > end-code) FAIL; code += offset; break; @@ -2985,11 +2985,11 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) GET_ARG; prefix_len = arg; GET_ARG; /* prefix skip */ /* Here comes the prefix string */ - if (code+prefix_len < code || code+prefix_len > newcode) + if (prefix_len > newcode-code) FAIL; code += prefix_len; /* And here comes the overlap table */ - if (code+prefix_len < code || code+prefix_len > newcode) + if (prefix_len > newcode-code) FAIL; /* Each overlap value should be < prefix_len */ for (i = 0; i < prefix_len; i++) { @@ -3118,7 +3118,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 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) { VTRACE(("both then and else parts present\n")); -- cgit v0.12