|
| 1 | +From 5dcc443dba039b305a510c01883e9f34e42656ae Mon Sep 17 00:00:00 2001 |
| 2 | +From: Denys Vlasenko <vda.linux@googlemail.com> |
| 3 | +Date: Fri, 26 May 2023 19:36:58 +0200 |
| 4 | +Subject: [PATCH 01/19] awk: fix use-after-realloc (CVE-2021-42380), closes |
| 5 | + 15601 |
| 6 | + |
| 7 | +Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> |
| 8 | +Signed-off-by: Muhammad Falak R Wani <falakreyaz@gmail.com> |
| 9 | +--- |
| 10 | + editors/awk.c | 26 ++++++++++++++++++++------ |
| 11 | + 1 file changed, 20 insertions(+), 6 deletions(-) |
| 12 | + |
| 13 | +diff --git a/editors/awk.c b/editors/awk.c |
| 14 | +index 728ee8685..2af823808 100644 |
| 15 | +--- a/editors/awk.c |
| 16 | ++++ b/editors/awk.c |
| 17 | +@@ -555,7 +555,7 @@ struct globals { |
| 18 | + const char *g_progname; |
| 19 | + int g_lineno; |
| 20 | + int nfields; |
| 21 | +- int maxfields; /* used in fsrealloc() only */ |
| 22 | ++ unsigned maxfields; |
| 23 | + var *Fields; |
| 24 | + char *g_pos; |
| 25 | + char g_saved_ch; |
| 26 | +@@ -1931,9 +1931,9 @@ static void fsrealloc(int size) |
| 27 | + { |
| 28 | + int i, newsize; |
| 29 | + |
| 30 | +- if (size >= maxfields) { |
| 31 | +- /* Sanity cap, easier than catering for overflows */ |
| 32 | +- if (size > 0xffffff) |
| 33 | ++ if ((unsigned)size >= maxfields) { |
| 34 | ++ /* Sanity cap, easier than catering for over/underflows */ |
| 35 | ++ if ((unsigned)size > 0xffffff) |
| 36 | + bb_die_memory_exhausted(); |
| 37 | + |
| 38 | + i = maxfields; |
| 39 | +@@ -2891,6 +2891,7 @@ static var *evaluate(node *op, var *res) |
| 40 | + uint32_t opinfo; |
| 41 | + int opn; |
| 42 | + node *op1; |
| 43 | ++ var *old_Fields_ptr; |
| 44 | + |
| 45 | + opinfo = op->info; |
| 46 | + opn = (opinfo & OPNMASK); |
| 47 | +@@ -2899,10 +2900,16 @@ static var *evaluate(node *op, var *res) |
| 48 | + debug_printf_eval("opinfo:%08x opn:%08x\n", opinfo, opn); |
| 49 | + |
| 50 | + /* execute inevitable things */ |
| 51 | ++ old_Fields_ptr = NULL; |
| 52 | + if (opinfo & OF_RES1) { |
| 53 | + if ((opinfo & OF_REQUIRED) && !op1) |
| 54 | + syntax_error(EMSG_TOO_FEW_ARGS); |
| 55 | + L.v = evaluate(op1, TMPVAR0); |
| 56 | ++ /* Does L.v point to $n variable? */ |
| 57 | ++ if ((size_t)(L.v - Fields) < maxfields) { |
| 58 | ++ /* yes, remember where Fields[] is */ |
| 59 | ++ old_Fields_ptr = Fields; |
| 60 | ++ } |
| 61 | + if (opinfo & OF_STR1) { |
| 62 | + L.s = getvar_s(L.v); |
| 63 | + debug_printf_eval("L.s:'%s'\n", L.s); |
| 64 | +@@ -2921,8 +2928,15 @@ static var *evaluate(node *op, var *res) |
| 65 | + */ |
| 66 | + if (opinfo & OF_RES2) { |
| 67 | + R.v = evaluate(op->r.n, TMPVAR1); |
| 68 | +- //TODO: L.v may be invalid now, set L.v to NULL to catch bugs? |
| 69 | +- //L.v = NULL; |
| 70 | ++ /* Seen in $5=$$5=$0: |
| 71 | ++ * Evaluation of R.v ($$5=$0 expression) |
| 72 | ++ * made L.v ($5) invalid. It's detected here. |
| 73 | ++ */ |
| 74 | ++ if (old_Fields_ptr) { |
| 75 | ++ //if (old_Fields_ptr != Fields) |
| 76 | ++ // debug_printf_eval("L.v moved\n"); |
| 77 | ++ L.v += Fields - old_Fields_ptr; |
| 78 | ++ } |
| 79 | + if (opinfo & OF_STR2) { |
| 80 | + R.s = getvar_s(R.v); |
| 81 | + debug_printf_eval("R.s:'%s'\n", R.s); |
| 82 | +-- |
| 83 | +2.46.0 |
0 commit comments