ref: 1a3cfdc5f7293bf426a14056002204169790b11b
parent: 83a948f226f910ddabb573499996f55502d19b23
author: qwx <qwx@sciops.net>
date: Wed Jan 7 13:07:47 EST 2026
fix use after free in regexp cache
--- a/lib.c
+++ b/lib.c
@@ -399,7 +399,8 @@
break;
}
}
- return i;
+ releasere(p);
+ return i;
}
void recbld(void) /* create $0 from $1..$NF if necessary */
--- a/proto.h
+++ b/proto.h
@@ -11,6 +11,7 @@
extern void unput(int);
extern void unputstr(char *);
+extern void releasere(void *);
extern void *compre(char *);
extern int hexstr(char **);
extern void quoted(char **, char **, char *);
--- a/re.c
+++ b/re.c
@@ -40,11 +40,24 @@
{char *re;
int use;
+ int inuse;
Reprog *program;
} pattern[NPATS];
static int npats; /* cache fill level */
+void
+releasere(void *p)
+{+ int i;
+
+ for (i = 0; i < npats; i++)
+ if (pattern[i].program == p) {+ pattern[i].inuse--;
+ break;
+ }
+}
+
/* Compile a pattern */
void
*compre(char *pat)
@@ -57,6 +70,7 @@
for (i = 0; i < npats; i++)
if (!strcmp(pat, pattern[i].re)) {pattern[i].use++;
+ pattern[i].inuse++;
return((void *) pattern[i].program);
}
}
@@ -138,20 +152,25 @@
if (npats < NPATS) /* Room in cache */
i = npats++;
else { /* Throw out least used */- int use = pattern[0].use;
- i = 0;
- for (j = 1; j < NPATS; j++) {- if (pattern[j].use < use) {+ int use = -1U;
+ i = -1;
+ for (j = 0; j < NPATS; j++) {+ if (pattern[j].inuse == 0 && pattern[j].use < use) {use = pattern[j].use;
i = j;
}
}
- xfree(pattern[i].program);
- xfree(pattern[i].re);
+ if (i >= 0) {+ xfree(pattern[i].program);
+ xfree(pattern[i].re);
+ }
}
- pattern[i].re = tostring(pat);
- pattern[i].program = program;
- pattern[i].use = 1;
+ if (i >= 0) {+ pattern[i].re = tostring(pat);
+ pattern[i].program = program;
+ pattern[i].use = 1;
+ pattern[i].inuse = 1;
+ }
}
return((void *) program);
}
--- a/run.c
+++ b/run.c
@@ -582,6 +582,7 @@
i = pmatch(p, s, s);
else
i = match(p, s, s);
+ releasere(p);
if (istemp(x))
tfree(x);
if (n == MATCHFCN) {@@ -1301,8 +1302,7 @@
else
setsymtab(num, t, 0.0, STR, (Array *) ap->sval);
spdone:
- p = nil;
- USED(p);
+ releasere(p);
} else if (sep == ' ') { for (n = 0; ; ) {while (*s == ' ' || *s == '\t' || *s == '\n')
@@ -1863,6 +1863,7 @@
setsval(x, buf); /* BUG: should be able to avoid copy */
result = True;;
}
+ releasere(p);
if (istemp(x))
tfree(x);
if (istemp(y))
@@ -1960,6 +1961,7 @@
;
setsval(x, buf); /* BUG: should be able to avoid copy + free */
}
+ releasere(p);
if (istemp(x))
tfree(x);
if (istemp(y))
--
⑨