When the accumulated trie key exceeds the fixed-size line buffer,
linebuf_get() returns NULL. trie_fnmatch_f() passed that NULL straight
into fnmatch() as the pattern, causing a SIGSEGV on a crafted hwdb.bin
(reachable now that recursion is capped rather than overflowing the
stack first). Treat the NULL like the other corruption checks and
return -EBADMSG.
Follow-up for
73fea38cf1344e08213bb10bfc1e1a98382aee78
Fixes https://github.com/systemd/systemd/issues/42376
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
linebuf_rem_char(buf);
}
- if (le64toh(node->values_count) && fnmatch(linebuf_get(buf), search, 0) == 0)
- for (i = 0; i < le64toh(node->values_count); i++) {
- err = hwdb_add_property(hwdb, trie_node_value(hwdb, node, i));
- if (err < 0)
- return err;
- }
+ if (le64toh(node->values_count) != 0) {
+ const char *line = linebuf_get(buf);
+ if (!line)
+ return -EBADMSG;
+
+ if (fnmatch(line, search, 0) == 0)
+ for (i = 0; i < le64toh(node->values_count); i++) {
+ err = hwdb_add_property(hwdb, trie_node_value(hwdb, node, i));
+ if (err < 0)
+ return err;
+ }
+ }
linebuf_rem(buf, len);
return 0;