ref: 602d0df21c320e80a4fdb429219c5341e9602709
parent: 00b4628de66236f95e56919391ce3cf65fdbf23f
author: qwx <qwx@sciops.net>
date: Sun Dec 7 17:38:24 EST 2025
awk: fix use-after-free when ARGV is deleted
--- a/sys/src/cmd/awk/awk.h
+++ b/sys/src/cmd/awk/awk.h
@@ -81,6 +81,7 @@
extern Cell *nfloc; /* NF */
extern Cell *rstartloc; /* RSTART */
extern Cell *rlengthloc; /* RLENGTH */
+extern Cell *argvloc; /* ARGV */
/* Cell.tval values: */
#define NUM 01 /* number value is valid */
--- a/sys/src/cmd/awk/lib.c
+++ b/sys/src/cmd/awk/lib.c
@@ -214,11 +214,16 @@
char *getargv(int n) /* get ARGV[n] */
{Cell *x;
+ Array *ap;
char *s, temp[50];
- extern Array *ARGVtab;
+ ap = (Array *) argvloc->sval;
+ if (ap == nil)
+ return EMPTY;
sprint(temp, "%d", n);
- x = setsymtab(temp, EMPTY, 0.0, STR, ARGVtab);
+ x = lookup(temp, ap);
+ if (x == nil)
+ return EMPTY;
s = getsval(x);
dprint( ("getargv(%d) returns |%s|\n", n, s) );return s;
--- a/sys/src/cmd/awk/tran.c
+++ b/sys/src/cmd/awk/tran.c
@@ -54,11 +54,11 @@
Cell *nrloc; /* NR */
Cell *nfloc; /* NF */
Cell *fnrloc; /* FNR */
-Array *ARGVtab; /* symbol table containing ARGV[...] */
Array *ENVtab; /* symbol table containing ENVIRON[...] */
Cell *rstartloc; /* RSTART */
Cell *rlengthloc; /* RLENGTH */
Cell *symtabloc; /* SYMTAB */
+Cell *argvloc; /* ARGV */
Cell *nullloc; /* a guaranteed empty cell */
Node *nullnode; /* zero&null, converted into a node for comparisons */
@@ -98,6 +98,7 @@
void arginit(int ac, char **av) /* set up ARGV and ARGC */
{Cell *cp;
+ Array *ap;
int i;
char temp[50];
Awkfloat f;
@@ -104,14 +105,15 @@
AARGC = &setsymtab("ARGC", EMPTY, (Awkfloat) ac, NUM, symtab)->fval; cp = setsymtab("ARGV", EMPTY, 0.0, ARR, symtab);- ARGVtab = makesymtab(NSYMTAB); /* could be (int) ARGC as well */
- cp->sval = (char *) ARGVtab;
+ argvloc = cp;
+ ap = makesymtab(NSYMTAB); /* could be (int) ARGC as well */
+ cp->sval = (char *) ap;
for (i = 0; i < ac; i++) {sprint(temp, "%d", i);
if (to_number(*av, &f, nil))
- setsymtab(temp, *av, f, STR|NUM, ARGVtab);
+ setsymtab(temp, *av, f, STR|NUM, ap);
else
- setsymtab(temp, *av, 0.0, STR, ARGVtab);
+ setsymtab(temp, *av, 0.0, STR, ap);
av++;
}
}
--
⑨