History

user_events: Handle matching arguments from dyn_events

Ensures that when dynamic events requests a match with arguments that they match what is in the user_event. Link: https://lkml.kernel.org/r/20220118204326.2169-4-beaub@linux.microsoft.com

Beau Belgrave committed 4 years ago

Commit 9aed4e11 parent aa3b2b41 file · +76 −1Browse files

Showing the changes to kernel (1 of 1 file). Show all

Unified · Split

kernel/trace/trace_events_user.c+76−1
@@ -39,6 +39,7 @@ · 38 unmodified lines
3939 #define MAX_EVENT_DESC 512
4040 #define EVENT_NAME(user_event) ((user_event)->tracepoint.name)
4141 #define MAX_FIELD_ARRAY_SIZE 1024
42+#define MAX_FIELD_ARG_NAME 256
4243
4344 static char *register_page_data;
4445
@@ -700,13 +701,87 @@ static int user_event_free(struct dyn_event *ev) · 655 unmodified lines
700701 return destroy_user_event(user);
701702 }
702703
704+static bool user_field_match(struct ftrace_event_field *field, int argc,
705+ const char **argv, int *iout)
706+{
707+ char *field_name, *arg_name;
708+ int len, pos, i = *iout;
709+ bool colon = false, match = false;
710+
711+ if (i >= argc)
712+ return false;
713+
714+ len = MAX_FIELD_ARG_NAME;
715+ field_name = kmalloc(len, GFP_KERNEL);
716+ arg_name = kmalloc(len, GFP_KERNEL);
717+
718+ if (!arg_name || !field_name)
719+ goto out;
720+
721+ pos = 0;
722+
723+ for (; i < argc; ++i) {
724+ if (i != *iout)
725+ pos += snprintf(arg_name + pos, len - pos, " ");
726+
727+ pos += snprintf(arg_name + pos, len - pos, argv[i]);
728+
729+ if (strchr(argv[i], ';')) {
730+ ++i;
731+ colon = true;
732+ break;
733+ }
734+ }
735+
736+ pos = 0;
737+
738+ pos += snprintf(field_name + pos, len - pos, field->type);
739+ pos += snprintf(field_name + pos, len - pos, " ");
740+ pos += snprintf(field_name + pos, len - pos, field->name);
741+
742+ if (colon)
743+ pos += snprintf(field_name + pos, len - pos, ";");
744+
745+ *iout = i;
746+
747+ match = strcmp(arg_name, field_name) == 0;
748+out:
749+ kfree(arg_name);
750+ kfree(field_name);
751+
752+ return match;
753+}
754+
755+static bool user_fields_match(struct user_event *user, int argc,
756+ const char **argv)
757+{
758+ struct ftrace_event_field *field, *next;
759+ struct list_head *head = &user->fields;
760+ int i = 0;
761+
762+ list_for_each_entry_safe_reverse(field, next, head, link)
763+ if (!user_field_match(field, argc, argv, &i))
764+ return false;
765+
766+ if (i != argc)
767+ return false;
768+
769+ return true;
770+}
771+
703772 static bool user_event_match(const char *system, const char *event,
704773 int argc, const char **argv, struct dyn_event *ev)
705774 {
706775 struct user_event *user = container_of(ev, struct user_event, devent);
776+ bool match;
707777
708− return strcmp(EVENT_NAME(user), event) == 0 &&
778+ match = strcmp(EVENT_NAME(user), event) == 0 &&
709779 (!system || strcmp(system, USER_EVENTS_SYSTEM) == 0);
780+
781+ if (match && argc > 0)
782+ match = user_fields_match(user, argc, argv);
783+
784+ return match;
710785 }
711786
712787 static struct dyn_event_operations user_event_dops = {