shithub: kwa

Download patch

ref: 6107b9c6c24e358901ad588b8e9053bd70cd8aa2
parent: 3cd994e757586d7a6f54c2e6987065a958bf455e
author: qwx <qwx@sciops.net>
date: Wed Jan 7 13:14:32 EST 2026

fix use-after-free when ARGV is deleted (fromt 9front)

--- a/awk.h
+++ b/awk.h
@@ -76,6 +76,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/lib.c
+++ b/lib.c
@@ -190,11 +190,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/tran.c
+++ b/tran.c
@@ -30,11 +30,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 */
@@ -74,6 +74,7 @@
 void arginit(int ac, char **av)	/* set up ARGV and ARGC */
 {
 	Cell *cp;
+	Array *ap;
 	int i;
 	char temp[50];
 	Awkfloat f;
@@ -80,14 +81,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++;
 	}
 }
--