aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editors/awk.c26
-rwxr-xr-xtestsuite/awk.tests55
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
489testing '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
5150
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
488exit $FAILCOUNT 543exit $FAILCOUNT