DF-0362 / fix.diff
diff --git a/sys/net/pf/pf_table.c b/sys/net/pf/pf_table.c --- a/sys/net/pf/pf_table.c +++ b/sys/net/pf/pf_table.c @@ -1742,14 +1742,26 @@ size_t siz = MAXPATHLEN; int i; + /* anchor must be NUL-terminated within siz bytes, otherwise the + slash-stripping loop below could read past the array (the byte + immediately after pfrt_anchor is pfrt_name, also attacker-controlled), + making 'off' exceed 'siz' and causing siz - off to wrap as size_t + in the subsequent bcopy(). */ + if (anchor[siz - 1] != '\0') + return (-1); if (anchor[0] == '/') { char *path; int off; path = anchor; off = 1; - while (*++path == '/') + while (off < siz && *++path == '/') off++; + /* off == siz cannot happen now (anchor[siz-1] == 0 was checked + above, so the loop stops at the NUL at the latest), but keep + the guard as defense-in-depth. */ + if (off >= siz) + return (-1); bcopy(path, anchor, siz - off); memset(anchor + siz - off, 0, off); } |