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/trace (1 of 1 file). Show all

Unified · Split

kernel/trace/trace_events_user.c+76−1
@@ -39,6 +39,7 @@ · 38 unmodified lines
39#define MAX_EVENT_DESC 51239#define MAX_EVENT_DESC 512
40#define EVENT_NAME(user_event) ((user_event)->tracepoint.name)40#define EVENT_NAME(user_event) ((user_event)->tracepoint.name)
41#define MAX_FIELD_ARRAY_SIZE 102441#define MAX_FIELD_ARRAY_SIZE 1024
42#define MAX_FIELD_ARG_NAME 256
42 43
43static char *register_page_data;44static char *register_page_data;
44 45
@@ -700,13 +701,87 @@ static int user_event_free(struct dyn_event *ev) · 655 unmodified lines
700 return destroy_user_event(user);701 return destroy_user_event(user);
701}702}
702 703
704static 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;
748out:
749 kfree(arg_name);
750 kfree(field_name);
751
752 return match;
753}
754
755static 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
703static bool user_event_match(const char *system, const char *event,772static bool user_event_match(const char *system, const char *event,
704 int argc, const char **argv, struct dyn_event *ev)773 int argc, const char **argv, struct dyn_event *ev)
705{774{
706 struct user_event *user = container_of(ev, struct user_event, devent);775 struct user_event *user = container_of(ev, struct user_event, devent);
776 bool match;
707 777
708 return strcmp(EVENT_NAME(user), event) == 0 &&778 match = strcmp(EVENT_NAME(user), event) == 0 &&
709 (!system || strcmp(system, USER_EVENTS_SYSTEM) == 0);779 (!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;
710}785}
711 786
712static struct dyn_event_operations user_event_dops = {787static struct dyn_event_operations user_event_dops = {