| 1 | # http://sourceware.org/bugzilla/show_bug.cgi?id=15078 |
| 2 | # CVE-2013-0242 |
| 3 | # ChangeLog, NEWS and new test removed to apply clean |
| 4 | |
| 5 | commit a445af0bc722d620afed7683cd320c0e4c7c6059 |
| 6 | Author: Andreas Schwab <schwab@suse.de> |
| 7 | Date: Tue Jan 29 14:45:15 2013 +0100 |
| 8 | |
| 9 | Fix buffer overrun in regexp matcher |
| 10 | |
| 11 | diff --git a/posix/regexec.c b/posix/regexec.c |
| 12 | index 7f2de85..5ca2bf6 100644 |
| 13 | --- a/posix/regexec.c |
| 14 | +++ b/posix/regexec.c |
| 15 | @@ -197,7 +197,7 @@ static int group_nodes_into_DFAstates (const re_dfa_t *dfa, |
| 16 | static int check_node_accept (const re_match_context_t *mctx, |
| 17 | const re_token_t *node, int idx) |
| 18 | internal_function; |
| 19 | -static reg_errcode_t extend_buffers (re_match_context_t *mctx) |
| 20 | +static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len) |
| 21 | internal_function; |
| 22 | \f |
| 23 | /* Entry point for POSIX code. */ |
| 24 | @@ -1160,7 +1160,7 @@ check_matching (re_match_context_t *mctx, int fl_longest_match, |
| 25 | || (BE (next_char_idx >= mctx->input.valid_len, 0) |
| 26 | && mctx->input.valid_len < mctx->input.len)) |
| 27 | { |
| 28 | - err = extend_buffers (mctx); |
| 29 | + err = extend_buffers (mctx, next_char_idx + 1); |
| 30 | if (BE (err != REG_NOERROR, 0)) |
| 31 | { |
| 32 | assert (err == REG_ESPACE); |
| 33 | @@ -1738,7 +1738,7 @@ clean_state_log_if_needed (re_match_context_t *mctx, int next_state_log_idx) |
| 34 | && mctx->input.valid_len < mctx->input.len)) |
| 35 | { |
| 36 | reg_errcode_t err; |
| 37 | - err = extend_buffers (mctx); |
| 38 | + err = extend_buffers (mctx, next_state_log_idx + 1); |
| 39 | if (BE (err != REG_NOERROR, 0)) |
| 40 | return err; |
| 41 | } |
| 42 | @@ -2792,7 +2792,7 @@ get_subexp (re_match_context_t *mctx, int bkref_node, int bkref_str_idx) |
| 43 | if (bkref_str_off >= mctx->input.len) |
| 44 | break; |
| 45 | |
| 46 | - err = extend_buffers (mctx); |
| 47 | + err = extend_buffers (mctx, bkref_str_off + 1); |
| 48 | if (BE (err != REG_NOERROR, 0)) |
| 49 | return err; |
| 50 | |
| 51 | @@ -4102,7 +4102,7 @@ check_node_accept (const re_match_context_t *mctx, const re_token_t *node, |
| 52 | |
| 53 | static reg_errcode_t |
| 54 | internal_function __attribute_warn_unused_result__ |
| 55 | -extend_buffers (re_match_context_t *mctx) |
| 56 | +extend_buffers (re_match_context_t *mctx, int min_len) |
| 57 | { |
| 58 | reg_errcode_t ret; |
| 59 | re_string_t *pstr = &mctx->input; |
| 60 | @@ -4111,8 +4111,10 @@ extend_buffers (re_match_context_t *mctx) |
| 61 | if (BE (INT_MAX / 2 / sizeof (re_dfastate_t *) <= pstr->bufs_len, 0)) |
| 62 | return REG_ESPACE; |
| 63 | |
| 64 | - /* Double the lengthes of the buffers. */ |
| 65 | - ret = re_string_realloc_buffers (pstr, MIN (pstr->len, pstr->bufs_len * 2)); |
| 66 | + /* Double the lengthes of the buffers, but allocate at least MIN_LEN. */ |
| 67 | + ret = re_string_realloc_buffers (pstr, |
| 68 | + MAX (min_len, |
| 69 | + MIN (pstr->len, pstr->bufs_len * 2))); |
| 70 | if (BE (ret != REG_NOERROR, 0)) |
| 71 | return ret; |
| 72 | |