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;


Reply via email to