From: Masami Hiramatsu (Google) <[email protected]>

In parse_pred(), when parsing an unquoted operand for function events,
the loop only stops at ')', '&', '|', or the NUL terminator.

However, calc_stack() parses '(', '\'', and '"' independently to
determine stack depth and string boundaries. If an unquoted function
operand contains stray quotes or an open parenthesis (e.g. "ip == foo'bar"
or "ip == foo(bar)"), parse_pred() consumes them as part of the function
name operand, causing parse_pred() and calc_stack() to desynchronize.

Reject unquoted function event operands containing '(', '\'', or '"'
by reporting FILT_ERR_INVALID_VALUE.

Signed-off-by: Masami Hiramatsu (Google) <[email protected]>
---
Changes in v4:
 - Drop Fixes and Cc: stable tags since this is an error log improvement
   cleanup rather than a bug fix, as pointed out by Steven Rostedt.
Changes in v3:
 - Split from the monolithic function event parsing patch into a
   standalone patch rejecting stray quotes and '(' in unquoted operands.
---
 kernel/trace/trace_events_filter.c |   14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/kernel/trace/trace_events_filter.c 
b/kernel/trace/trace_events_filter.c
index 0a362ccb14ad..e91ec41bfd2a 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -1869,9 +1869,17 @@ static int parse_pred(const char *str, void *data,
                for (; str[i]; i++) {
                        if (q && str[i] == q)
                                break;
-                       if (!q && (str[i] == ')' || str[i] == '&' ||
-                                  str[i] == '|'))
-                               break;
+                       if (!q) {
+                               if (str[i] == ')' || str[i] == '&' ||
+                                   str[i] == '|')
+                                       break;
+                               if (str[i] == '(' || str[i] == '\'' ||
+                                   str[i] == '"') {
+                                       parse_error(pe, FILT_ERR_INVALID_VALUE,
+                                                   pos + i);
+                                       goto err_free;
+                               }
+                       }
                }
                if (q && !str[i]) {
                        parse_error(pe, FILT_ERR_MISSING_QUOTE, pos + i);


Reply via email to