tracing/filter: Do not allow infix to exceed end of string
[pandora-kernel.git] / kernel / trace / trace_events_filter.c
index ced69da..52adf02 100644 (file)
@@ -1056,6 +1056,9 @@ static void parse_init(struct filter_parse_state *ps,
 
 static char infix_next(struct filter_parse_state *ps)
 {
+       if (!ps->infix.cnt)
+               return 0;
+
        ps->infix.cnt--;
 
        return ps->infix.string[ps->infix.tail++];
@@ -1071,6 +1074,9 @@ static char infix_peek(struct filter_parse_state *ps)
 
 static void infix_advance(struct filter_parse_state *ps)
 {
+       if (!ps->infix.cnt)
+               return;
+
        ps->infix.cnt--;
        ps->infix.tail++;
 }
@@ -1369,19 +1375,28 @@ static int check_preds(struct filter_parse_state *ps)
 {
        int n_normal_preds = 0, n_logical_preds = 0;
        struct postfix_elt *elt;
+       int cnt = 0;
 
        list_for_each_entry(elt, &ps->postfix, list) {
-               if (elt->op == OP_NONE)
+               if (elt->op == OP_NONE) {
+                       cnt++;
                        continue;
+               }
 
                if (elt->op == OP_AND || elt->op == OP_OR) {
                        n_logical_preds++;
+                       cnt--;
                        continue;
                }
+               if (elt->op != OP_NOT)
+                       cnt--;
                n_normal_preds++;
+               /* all ops should have operands */
+               if (cnt < 0)
+                       break;
        }
 
-       if (!n_normal_preds || n_logical_preds >= n_normal_preds) {
+       if (cnt != 1 || !n_normal_preds || n_logical_preds >= n_normal_preds) {
                parse_error(ps, FILT_ERR_INVALID_FILTER, 0);
                return -EINVAL;
        }