libregexp: bump LISTSIZE 10 → 12 to dodge thread-list off-by-one
rregexec's overflow check `_renewthread(...) == nle` where
`nle = list + LISTSIZE - 2` catches the case where
_renewthread fills slot LISTSIZE-2, but misses an
OR-instruction mid-list walk that fills slot LISTSIZE-1 and
writes its sentinel at slot LISTSIZE — one byte out of bounds.
The OOB write corrupts heap memory adjacent to the regex
engine's stack.
The 9legacy tree has one regex that fills the thread list
past 10: abaco's URL validation regex with 10 protocol
alternatives (https?|ftp|file|gopher|mailto|news|nntp|telnet|
wais|prospero). Bumping LISTSIZE to 12 gives that NFA two
slots of headroom so the overflow never fires. 12 is the
largest single-line bump that doesn't push rregexec2's
fallback array (Relist relist0[5*LISTSIZE], 520 B per
Relist) over its 64 KB thread stack.
The off-by-one itself is unfixed. The proper fix is to make
_renewthread bound-aware regardless of where the walk starts,
or change every == nle / == tle to >= and guarantee the
spare slot — a multi-site change across regaux.c, regexec.c,
and rregexec.c, out of scope for this single-line bump.
--- sys/src/libregexp/regcomp.h
+++ sys/src/libregexp/regcomp.h
@@ -36,7 +36,7 @@
/*
* regexec execution lists
*/
-#define LISTSIZE 10
+#define LISTSIZE 12
#define BIGLISTSIZE (25*LISTSIZE)
typedef struct Relist Relist;
struct Relist
|