diff options
-rw-r--r-- | editors/awk.c | 26 | ||||
-rwxr-xr-x | 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 { | |||
555 | const char *g_progname; | 555 | const char *g_progname; |
556 | int g_lineno; | 556 | int g_lineno; |
557 | int nfields; | 557 | int nfields; |
558 | int maxfields; /* used in fsrealloc() only */ | 558 | unsigned maxfields; |
559 | var *Fields; | 559 | var *Fields; |
560 | char *g_pos; | 560 | char *g_pos; |
561 | char g_saved_ch; | 561 | char g_saved_ch; |
@@ -1931,9 +1931,9 @@ static void fsrealloc(int size) | |||
1931 | { | 1931 | { |
1932 | int i, newsize; | 1932 | int i, newsize; |
1933 | 1933 | ||
1934 | if (size >= maxfields) { | 1934 | if ((unsigned)size >= maxfields) { |
1935 | /* Sanity cap, easier than catering for overflows */ | 1935 | /* Sanity cap, easier than catering for over/underflows */ |
1936 | if (size > 0xffffff) | 1936 | if ((unsigned)size > 0xffffff) |
1937 | bb_die_memory_exhausted(); | 1937 | bb_die_memory_exhausted(); |
1938 | 1938 | ||
1939 | i = maxfields; | 1939 | i = maxfields; |
@@ -2891,6 +2891,7 @@ static var *evaluate(node *op, var *res) | |||
2891 | uint32_t opinfo; | 2891 | uint32_t opinfo; |
2892 | int opn; | 2892 | int opn; |
2893 | node *op1; | 2893 | node *op1; |
2894 | var *old_Fields_ptr; | ||
2894 | 2895 | ||
2895 | opinfo = op->info; | 2896 | opinfo = op->info; |
2896 | opn = (opinfo & OPNMASK); | 2897 | opn = (opinfo & OPNMASK); |
@@ -2899,10 +2900,16 @@ static var *evaluate(node *op, var *res) | |||
2899 | debug_printf_eval("opinfo:%08x opn:%08x\n", opinfo, opn); | 2900 | debug_printf_eval("opinfo:%08x opn:%08x\n", opinfo, opn); |
2900 | 2901 | ||
2901 | /* execute inevitable things */ | 2902 | /* execute inevitable things */ |
2903 | old_Fields_ptr = NULL; | ||
2902 | if (opinfo & OF_RES1) { | 2904 | if (opinfo & OF_RES1) { |
2903 | if ((opinfo & OF_REQUIRED) && !op1) | 2905 | if ((opinfo & OF_REQUIRED) && !op1) |
2904 | syntax_error(EMSG_TOO_FEW_ARGS); | 2906 | syntax_error(EMSG_TOO_FEW_ARGS); |
2905 | L.v = evaluate(op1, TMPVAR0); | 2907 | L.v = evaluate(op1, TMPVAR0); |
2908 | /* Does L.v point to $n variable? */ | ||
2909 | if ((size_t)(L.v - Fields) < maxfields) { | ||
2910 | /* yes, remember where Fields[] is */ | ||
2911 | old_Fields_ptr = Fields; | ||
2912 | } | ||
2906 | if (opinfo & OF_STR1) { | 2913 | if (opinfo & OF_STR1) { |
2907 | L.s = getvar_s(L.v); | 2914 | L.s = getvar_s(L.v); |
2908 | debug_printf_eval("L.s:'%s'\n", L.s); | 2915 | debug_printf_eval("L.s:'%s'\n", L.s); |
@@ -2921,8 +2928,15 @@ static var *evaluate(node *op, var *res) | |||
2921 | */ | 2928 | */ |
2922 | if (opinfo & OF_RES2) { | 2929 | if (opinfo & OF_RES2) { |
2923 | R.v = evaluate(op->r.n, TMPVAR1); | 2930 | R.v = evaluate(op->r.n, TMPVAR1); |
2924 | //TODO: L.v may be invalid now, set L.v to NULL to catch bugs? | 2931 | /* Seen in $5=$$5=$0: |
2925 | //L.v = NULL; | 2932 | * Evaluation of R.v ($$5=$0 expression) |
2933 | * made L.v ($5) invalid. It's detected here. | ||
2934 | */ | ||
2935 | if (old_Fields_ptr) { | ||
2936 | //if (old_Fields_ptr != Fields) | ||
2937 | // debug_printf_eval("L.v moved\n"); | ||
2938 | L.v += Fields - old_Fields_ptr; | ||
2939 | } | ||
2926 | if (opinfo & OF_STR2) { | 2940 | if (opinfo & OF_STR2) { |
2927 | R.s = getvar_s(R.v); | 2941 | R.s = getvar_s(R.v); |
2928 | debug_printf_eval("R.s:'%s'\n", R.s); | 2942 | 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' \ | |||
485 | "" \ | 485 | "" \ |
486 | "foo" | 486 | "foo" |
487 | 487 | ||
488 | # User-supplied bug (SEGV) example, was causing use-after-realloc | ||
489 | testing 'awk assign while assign' \ | ||
490 | "awk '\$5=\$\$5=\$0'; echo \$?" \ | ||
491 | "\ | ||
492 | ─ process timing ────────────────────────────────────┬─ ─ process timing ────────────────────────────────────┬─ overall results ────┐ results ────┐ | ||
493 | │ 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 │ | ||
494 | │ 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 │ | ||
495 | │last saved crash : │last saved crash : none seen yet │saved crashes : 0 │ seen yet │saved crashes : 0 │ | ||
496 | │ last saved hang │ last saved hang : none seen yet │ saved hangs : 0 │ none seen yet │ saved hangs : 0 │ | ||
497 | ├─ cycle progress ─────────────────────┬─ ├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ coverage┴──────────────────────┤ | ||
498 | │ 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% │ | ||
499 | │ runs timed out │ runs timed out : 0 (0.00%) │ count coverage : 2.18 bits/tuple │ 0 (0.00%) │ count coverage : 2.18 bits/tuple │ | ||
500 | ├─ stage progress ─────────────────────┼─ ├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ in depth ─────────────────┤ | ||
501 | │ now trying : │ now trying : havoc │ favored items : 43 (20.67%) │ │ favored items : 43 (20.67%) │ | ||
502 | │ 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%) │ | ||
503 | │ total execs : │ total execs : 179k │ total crashes : 0 (0 saved) │ │ total crashes : 0 (0 saved) │ │ total execs : 179k │ total crashes : 0 (0 saved) │ | ||
504 | │ 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) │ | ||
505 | ├─ fuzzing strategy yields ├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ item geometry ───────┤ | ||
506 | │ 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 │ │ | ||
507 | │ byte flips : │ byte flips : 0/81, 0/71, 0/52 │ pending : 199 │ 0/71, 0/52 │ pending : 199 │ | ||
508 | │ arithmetics : 11/4494, │ arithmetics : 11/4494, 0/1153, 0/0 │ pend fav : 35 │ 0/0 │ pend fav : 35 │ | ||
509 | │ 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 │ | ||
510 | │ dictionary : 0/0, │ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 0 │ 0/0, 0/0 │ imported : 0 │ | ||
511 | │havoc/splice : 142/146k, 23/7616 │havoc/splice : 142/146k, 23/7616 │ stability : 100.00% │ stability : 100.00% │ | ||
512 | │py/custom/rq : unused, unused, │py/custom/rq : unused, unused, unused, unused ├───────────────────────┘ unused ├───────────────────────┘ | ||
513 | │ trim/eff : 57.02%/26, │ trim/eff : 57.02%/26, 0.00% │ [cpu000:100%] │ [cpu000:100%] | ||
514 | └────────────────────────────────────────────────────┘^C └────────────────────────────────────────────────────┘^C | ||
515 | 0 | ||
516 | " \ | ||
517 | "" \ | ||
518 | "\ | ||
519 | ─ process timing ────────────────────────────────────┬─ overall results ────┐ | ||
520 | │ run time : 0 days, 0 hrs, 0 min, 56 sec │ cycles done : 0 │ | ||
521 | │ last new find : 0 days, 0 hrs, 0 min, 1 sec │ corpus count : 208 │ | ||
522 | │last saved crash : none seen yet │saved crashes : 0 │ | ||
523 | │ last saved hang : none seen yet │ saved hangs : 0 │ | ||
524 | ├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ | ||
525 | │ now processing : 184.1 (88.5%) │ map density : 0.30% / 0.52% │ | ||
526 | │ runs timed out : 0 (0.00%) │ count coverage : 2.18 bits/tuple │ | ||
527 | ├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ | ||
528 | │ now trying : havoc │ favored items : 43 (20.67%) │ | ||
529 | │ stage execs : 11.2k/131k (8.51%) │ new edges on : 52 (25.00%) │ | ||
530 | │ total execs : 179k │ total crashes : 0 (0 saved) │ | ||
531 | │ exec speed : 3143/sec │ total tmouts : 0 (0 saved) │ | ||
532 | ├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ | ||
533 | │ bit flips : 11/648, 4/638, 5/618 │ levels : 4 │ | ||
534 | │ byte flips : 0/81, 0/71, 0/52 │ pending : 199 │ | ||
535 | │ arithmetics : 11/4494, 0/1153, 0/0 │ pend fav : 35 │ | ||
536 | │ known ints : 1/448, 0/1986, 0/2288 │ own finds : 207 │ | ||
537 | │ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 0 │ | ||
538 | │havoc/splice : 142/146k, 23/7616 │ stability : 100.00% │ | ||
539 | │py/custom/rq : unused, unused, unused, unused ├───────────────────────┘ | ||
540 | │ trim/eff : 57.02%/26, 0.00% │ [cpu000:100%] | ||
541 | └────────────────────────────────────────────────────┘^C" | ||
542 | |||
488 | exit $FAILCOUNT | 543 | exit $FAILCOUNT |