git: 9front

Download patch

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++;
 	}
 }
--