[git commit] awk: fix use-after-realloc (CVE-2021-42380), closes 15601
Denys Vlasenko
vda.linux at googlemail.com
Fri May 26 17:36:58 UTC 2023
commit: https://git.busybox.net/busybox/commit/?id=5dcc443dba039b305a510c01883e9f34e42656ae
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
editors/awk.c | 26 +++++++++++++++++++------
testsuite/awk.tests | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 75 insertions(+), 6 deletions(-)
diff --git a/editors/awk.c b/editors/awk.c
index 728ee8685..2af823808 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -555,7 +555,7 @@ struct globals {
const char *g_progname;
int g_lineno;
int nfields;
- int maxfields; /* used in fsrealloc() only */
+ unsigned maxfields;
var *Fields;
char *g_pos;
char g_saved_ch;
@@ -1931,9 +1931,9 @@ static void fsrealloc(int size)
{
int i, newsize;
- if (size >= maxfields) {
- /* Sanity cap, easier than catering for overflows */
- if (size > 0xffffff)
+ if ((unsigned)size >= maxfields) {
+ /* Sanity cap, easier than catering for over/underflows */
+ if ((unsigned)size > 0xffffff)
bb_die_memory_exhausted();
i = maxfields;
@@ -2891,6 +2891,7 @@ static var *evaluate(node *op, var *res)
uint32_t opinfo;
int opn;
node *op1;
+ var *old_Fields_ptr;
opinfo = op->info;
opn = (opinfo & OPNMASK);
@@ -2899,10 +2900,16 @@ static var *evaluate(node *op, var *res)
debug_printf_eval("opinfo:%08x opn:%08x\n", opinfo, opn);
/* execute inevitable things */
+ old_Fields_ptr = NULL;
if (opinfo & OF_RES1) {
if ((opinfo & OF_REQUIRED) && !op1)
syntax_error(EMSG_TOO_FEW_ARGS);
L.v = evaluate(op1, TMPVAR0);
+ /* Does L.v point to $n variable? */
+ if ((size_t)(L.v - Fields) < maxfields) {
+ /* yes, remember where Fields[] is */
+ old_Fields_ptr = Fields;
+ }
if (opinfo & OF_STR1) {
L.s = getvar_s(L.v);
debug_printf_eval("L.s:'%s'\n", L.s);
@@ -2921,8 +2928,15 @@ static var *evaluate(node *op, var *res)
*/
if (opinfo & OF_RES2) {
R.v = evaluate(op->r.n, TMPVAR1);
- //TODO: L.v may be invalid now, set L.v to NULL to catch bugs?
- //L.v = NULL;
+ /* Seen in $5=$$5=$0:
+ * Evaluation of R.v ($$5=$0 expression)
+ * made L.v ($5) invalid. It's detected here.
+ */
+ if (old_Fields_ptr) {
+ //if (old_Fields_ptr != Fields)
+ // debug_printf_eval("L.v moved\n");
+ L.v += Fields - old_Fields_ptr;
+ }
if (opinfo & OF_STR2) {
R.s = getvar_s(R.v);
debug_printf_eval("R.s:'%s'\n", R.s);
diff --git a/testsuite/awk.tests b/testsuite/awk.tests
index bbf0fbff1..ddc51047b 100755
--- a/testsuite/awk.tests
+++ b/testsuite/awk.tests
@@ -485,4 +485,59 @@ testing 'awk assign while test' \
"" \
"foo"
+# User-supplied bug (SEGV) example, was causing use-after-realloc
+testing 'awk assign while assign' \
+ "awk '\$5=\$\$5=\$0'; echo \$?" \
+ "\
+â process timing âââââââââââââââââââââââââââââââââââââ¬â â process timing âââââââââââââââââââââââââââââââââââââ¬â overall results âââââ results âââââ
+â run time : â run time : 0 days, 0 hrs, 0 min, 56 sec â cycles done : 0 â days, 0 hrs, 0 min, 56 sec â cycles done : 0 â
+â last new find â last new find : 0 days, 0 hrs, 0 min, 1 sec â corpus count : 208 â 0 days, 0 hrs, 0 min, 1 sec â corpus count : 208 â
+âlast saved crash : âlast saved crash : none seen yet âsaved crashes : 0 â seen yet âsaved crashes : 0 â
+â last saved hang â last saved hang : none seen yet â saved hangs : 0 â none seen yet â saved hangs : 0 â
+ââ cycle progress ââââââââââââââââââââââ¬â ââ cycle progress ââââââââââââââââââââââ¬â map coverageâ´ââââââââââââââââââââââ⤠coverageâ´âââââââââââââââââââââââ¤
+â now processing : â now processing : 184.1 (88.5%) â map density : 0.30% / 0.52% â (88.5%) â map density : 0.30% / 0.52% â â now processing : 184.1 (88.5%) â map density : 0.30% / 0.52% â
+â runs timed out â runs timed out : 0 (0.00%) â count coverage : 2.18 bits/tuple â 0 (0.00%) â count coverage : 2.18 bits/tuple â
+ââ stage progress ââââââââââââââââââââââ¼â ââ stage progress ââââââââââââââââââââââ¼â findings in depth âââââââââââââââââ⤠in depth ââââââââââââââââââ¤
+â now trying : â now trying : havoc â favored items : 43 (20.67%) â â favored items : 43 (20.67%) â
+â stage execs : â stage execs : 11.2k/131k (8.51%) â new edges on : 52 (25.00%) â (8.51%) â new edges on â stage execs : 11.2k/131k (8.51%) â new edges on : 52 (25.00%) â 52 (25.00%) â
+â total execs : â total execs : 179k â total crashes : 0 (0 saved) â â total crashes : 0 (0 saved) â â total execs : 179k â total crashes : 0 (0 saved) â
+â exec speed : â exec speed : 3143/sec â total tmouts : 0 (0 saved) â â total tmouts : 0 (0 saved) â
â exec speed : 3143/sec â total tmouts : 0 (0 saved) â
+ââ fuzzing strategy yields ââ fuzzing strategy yields âââââââââââââ´ââââââââââââââ¬â item geometry âââââââ⤠item geometry ââââââââ¤
+â bit flips : â bit flips : 11/648, 4/638, 5/618 â levels : 4 â 4/638, 5/618 â levels : â bit flips : 11/648, 4/638, 5/618 â levels : 4 â â
+â byte flips : â byte flips : 0/81, 0/71, 0/52 â pending : 199 â 0/71, 0/52 â pending : 199 â
+â arithmetics : 11/4494, â arithmetics : 11/4494, 0/1153, 0/0 â pend fav : 35 â 0/0 â pend fav : 35 â
+â known ints : 1/448, 0/1986, 0/2288 â own finds : 207 â known ints : â known ints : 1/448, 0/1986, 0/2288 â own finds : 207 â 0/1986, 0/2288 â own finds : 207 â
+â dictionary : 0/0, â dictionary : 0/0, 0/0, 0/0, 0/0 â imported : 0 â 0/0, 0/0 â imported : 0 â
+âhavoc/splice : 142/146k, 23/7616 âhavoc/splice : 142/146k, 23/7616 â stability : 100.00% â stability : 100.00% â
+âpy/custom/rq : unused, unused, âpy/custom/rq : unused, unused, unused, unused âââââââââââââââââââââââââ unused âââââââââââââââââââââââââ
+â trim/eff : 57.02%/26, â trim/eff : 57.02%/26, 0.00% â [cpu000:100%] â [cpu000:100%]
+ââââââââââââââââââââââââââââââââââââââââââââââââââââââ^C ââââââââââââââââââââââââââââââââââââââââââââââââââââââ^C
+0
+" \
+ "" \
+ "\
+â process timing âââââââââââââââââââââââââââââââââââââ¬â overall results âââââ
+â run time : 0 days, 0 hrs, 0 min, 56 sec â cycles done : 0 â
+â last new find : 0 days, 0 hrs, 0 min, 1 sec â corpus count : 208 â
+âlast saved crash : none seen yet âsaved crashes : 0 â
+â last saved hang : none seen yet â saved hangs : 0 â
+ââ cycle progress ââââââââââââââââââââââ¬â map coverageâ´âââââââââââââââââââââââ¤
+â now processing : 184.1 (88.5%) â map density : 0.30% / 0.52% â
+â runs timed out : 0 (0.00%) â count coverage : 2.18 bits/tuple â
+ââ stage progress ââââââââââââââââââââââ¼â findings in depth ââââââââââââââââââ¤
+â now trying : havoc â favored items : 43 (20.67%) â
+â stage execs : 11.2k/131k (8.51%) â new edges on : 52 (25.00%) â
+â total execs : 179k â total crashes : 0 (0 saved) â
+â exec speed : 3143/sec â total tmouts : 0 (0 saved) â
+ââ fuzzing strategy yields âââââââââââââ´ââââââââââââââ¬â item geometry ââââââââ¤
+â bit flips : 11/648, 4/638, 5/618 â levels : 4 â
+â byte flips : 0/81, 0/71, 0/52 â pending : 199 â
+â arithmetics : 11/4494, 0/1153, 0/0 â pend fav : 35 â
+â known ints : 1/448, 0/1986, 0/2288 â own finds : 207 â
+â dictionary : 0/0, 0/0, 0/0, 0/0 â imported : 0 â
+âhavoc/splice : 142/146k, 23/7616 â stability : 100.00% â
+âpy/custom/rq : unused, unused, unused, unused âââââââââââââââââââââââââ
+â trim/eff : 57.02%/26, 0.00% â [cpu000:100%]
+ââââââââââââââââââââââââââââââââââââââââââââââââââââââ^C"
+
exit $FAILCOUNT
More information about the busybox-cvs
mailing list