From: Masami Hiramatsu (Google) <[email protected]>
regex_match_end() calculates string length as "len - 1", assuming @len
is the string length including trailing '\0'. However, if @len is 0
(denoting an empty dynamic array where the size of @str is 0), "len - 1"
underflows to -1.
Furthermore, if the string length @len is less than or equal to the
pattern length r->len, the string contains fewer characters than the
pattern and cannot match.
Add a check for "len <= r->len" to safely return 0 without accessing
@str when @len is 0 or smaller than the pattern.
Fixes: a3291c14ecf0 ("tracing/filters: Fix MATCH_END_ONLY filter matching")
Cc: [email protected]
Signed-off-by: Masami Hiramatsu (Google) <[email protected]>
---
Changes in v3:
- Split zero-length string out-of-bounds fix from fixed-size string
matching.
- Return 0 immediately if "len <= r->len" without scanning the string.
Changes in v2:
- Check "len < r->len" to guard against negative lengths and avoid
calling strnlen() when the buffer capacity is smaller than pattern.
- Use strnlen(str, len) directly instead of calling strlen(str) when
len is 0, avoiding an out-of-bounds read on 0-length dynamic arrays.
---
kernel/trace/trace_events_filter.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/trace_events_filter.c
b/kernel/trace/trace_events_filter.c
index 5e74d2dae40a..59a0d3ba7274 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -1075,8 +1075,12 @@ static int regex_match_middle(char *str, struct regex
*r, int len)
static int regex_match_end(char *str, struct regex *r, int len)
{
- int strlen = len - 1;
+ int strlen;
+ if (len <= r->len)
+ return 0;
+
+ strlen = len - 1;
if (strlen >= r->len &&
memcmp(str + strlen - r->len, r->pattern, r->len) == 0)
return 1;