len = p - fmt;
 
        for (; field->type; field++) {
-               if (strncmp(field->name, fmt, len) ||
-                   field->name[len])
+               if (strncmp(field->name, fmt, len) || field->name[len])
                        continue;
                array_descriptor = strchr(field->type, '[');
                /* This is an array and is OK to dereference. */
        return false;
 }
 
+/* Return true if the argument pointer is safe */
+static bool process_pointer(const char *fmt, int len, struct trace_event_call *call)
+{
+       const char *r, *e, *a;
+
+       e = fmt + len;
+
+       /* Find the REC-> in the argument */
+       r = strstr(fmt, "REC->");
+       if (r && r < e) {
+               /*
+                * Addresses of events on the buffer, or an array on the buffer is
+                * OK to dereference. There's ways to fool this, but
+                * this is to catch common mistakes, not malicious code.
+                */
+               a = strchr(fmt, '&');
+               if ((a && (a < r)) || test_field(r, call))
+                       return true;
+       } else if ((r = strstr(fmt, "__get_dynamic_array(")) && r < e) {
+               return true;
+       } else if ((r = strstr(fmt, "__get_sockaddr(")) && r < e) {
+               return true;
+       }
+       return false;
+}
+
 /*
  * Examine the print fmt of the event looking for unsafe dereference
  * pointers using %p* that could be recorded in the trace event and
 {
        u64 dereference_flags = 0;
        bool first = true;
-       const char *fmt, *c, *r, *a;
+       const char *fmt;
        int parens = 0;
        char in_quote = 0;
        int start_arg = 0;
        int arg = 0;
-       int i;
+       int i, e;
 
        fmt = call->print_fmt;
 
                case ',':
                        if (in_quote || parens)
                                continue;
+                       e = i;
                        i++;
                        while (isspace(fmt[i]))
                                i++;
-                       start_arg = i;
-                       if (!(dereference_flags & (1ULL << arg)))
-                               goto next_arg;
 
-                       /* Find the REC-> in the argument */
-                       c = strchr(fmt + i, ',');
-                       r = strstr(fmt + i, "REC->");
-                       if (r && (!c || r < c)) {
-                               /*
-                                * Addresses of events on the buffer,
-                                * or an array on the buffer is
-                                * OK to dereference.
-                                * There's ways to fool this, but
-                                * this is to catch common mistakes,
-                                * not malicious code.
-                                */
-                               a = strchr(fmt + i, '&');
-                               if ((a && (a < r)) || test_field(r, call))
+                       /*
+                        * If start_arg is zero, then this is the start of the
+                        * first argument. The processing of the argument happens
+                        * when the end of the argument is found, as it needs to
+                        * handle paranthesis and such.
+                        */
+                       if (!start_arg) {
+                               start_arg = i;
+                               /* Balance out the i++ in the for loop */
+                               i--;
+                               continue;
+                       }
+
+                       if (dereference_flags & (1ULL << arg)) {
+                               if (process_pointer(fmt + start_arg, e - start_arg, call))
                                        dereference_flags &= ~(1ULL << arg);
-                       } else if ((r = strstr(fmt + i, "__get_dynamic_array(")) &&
-                                  (!c || r < c)) {
-                               dereference_flags &= ~(1ULL << arg);
-                       } else if ((r = strstr(fmt + i, "__get_sockaddr(")) &&
-                                  (!c || r < c)) {
-                               dereference_flags &= ~(1ULL << arg);
                        }
 
-               next_arg:
-                       i--;
+                       start_arg = i;
                        arg++;
+                       /* Balance out the i++ in the for loop */
+                       i--;
                }
        }
 
+       if (dereference_flags & (1ULL << arg)) {
+               if (process_pointer(fmt + start_arg, i - start_arg, call))
+                       dereference_flags &= ~(1ULL << arg);
+       }
+
        /*
         * If you triggered the below warning, the trace event reported
         * uses an unsafe dereference pointer %p*. As the data stored