History

tracing/user_events: Limit global user_event count

Operators want to be able to ensure enough tracepoints exist on the system for kernel components as well as for user components. Since there are only up to 64K events, by default allow up to half to be used by user events. Add a kernel sysctl parameter (kernel.user_events_max) to set a global limit that is honored among all groups on the system. This ensures hard limits can be setup to prevent user processes from consuming all event IDs on the system. Link: https://lkml.kernel.org/r/20230328235219.203-12-beaub@linux.microsoft.com

Beau Belgrave committed 3 years ago

Commit ce58e961 parent f9cce231 file · +47 −0Browse files

Unified · Split

kernel/trace/trace_events_user.c+47−0
@@ -20,6 +20,7 @@ · 19 unmodified lines
2020 #include <linux/types.h>
2121 #include <linux/uaccess.h>
2222 #include <linux/highmem.h>
23+#include <linux/init.h>
2324 #include <linux/user_events.h>
2425 #include "trace.h"
2526 #include "trace_dynevent.h"
@@ -61,6 +62,12 @@ struct user_event_group { · 35 unmodified lines
6162 /* Group for init_user_ns mapping, top-most group */
6263 static struct user_event_group *init_group;
6364
65+/* Max allowed events for the whole system */
66+static unsigned int max_user_events = 32768;
67+
68+/* Current number of events on the whole system */
69+static unsigned int current_user_events;
70+
6471 /*
6572 * Stores per-event properties, as users register events
6673 * within a file a user_event might be created if it does not
@@ -1241,6 +1248,8 @@ static int destroy_user_event(struct user_event *user) · 1174 unmodified lines
12411248 {
12421249 int ret = 0;
12431250
1251+ lockdep_assert_held(&event_mutex);
1252+
12441253 /* Must destroy fields before call removal */
12451254 user_event_destroy_fields(user);
12461255
@@ -1257,6 +1266,11 @@ static int destroy_user_event(struct user_event *user) · 10 unmodified lines
12571266 kfree(EVENT_NAME(user));
12581267 kfree(user);
12591268
1269+ if (current_user_events > 0)
1270+ current_user_events--;
1271+ else
1272+ pr_alert("BUG: Bad current_user_events\n");
1273+
12601274 return ret;
12611275 }
12621276
@@ -1744,6 +1758,11 @@ static int user_event_parse(struct user_event_group *group, char *name, · 481 unmodified lines
17441758
17451759 mutex_lock(&event_mutex);
17461760
1761+ if (current_user_events >= max_user_events) {
1762+ ret = -EMFILE;
1763+ goto put_user_lock;
1764+ }
1765+
17471766 ret = user_event_trace_register(user);
17481767
17491768 if (ret)
@@ -1755,6 +1774,7 @@ static int user_event_parse(struct user_event_group *group, char *name, · 5 unmodified lines
17551774 dyn_event_init(&user->devent, &user_event_dops);
17561775 dyn_event_add(&user->devent, &user->call);
17571776 hash_add(group->register_table, &user->node, key);
1777+ current_user_events++;
17581778
17591779 mutex_unlock(&event_mutex);
17601780
@@ -2390,6 +2410,31 @@ err: · 629 unmodified lines
23902410 return -ENODEV;
23912411 }
23922412
2413+static int set_max_user_events_sysctl(struct ctl_table *table, int write,
2414+ void *buffer, size_t *lenp, loff_t *ppos)
2415+{
2416+ int ret;
2417+
2418+ mutex_lock(&event_mutex);
2419+
2420+ ret = proc_douintvec(table, write, buffer, lenp, ppos);
2421+
2422+ mutex_unlock(&event_mutex);
2423+
2424+ return ret;
2425+}
2426+
2427+static struct ctl_table user_event_sysctls[] = {
2428+ {
2429+ .procname = "user_events_max",
2430+ .data = &max_user_events,
2431+ .maxlen = sizeof(unsigned int),
2432+ .mode = 0644,
2433+ .proc_handler = set_max_user_events_sysctl,
2434+ },
2435+ {}
2436+};
2437+
23932438 static int __init trace_events_user_init(void)
23942439 {
23952440 int ret;
@@ -2419,6 +2464,8 @@ static int __init trace_events_user_init(void) · 23 unmodified lines
24192464 if (dyn_event_register(&user_event_dops))
24202465 pr_warn("user_events could not register with dyn_events\n");
24212466
2467+ register_sysctl_init("kernel", user_event_sysctls);
2468+
24222469 return 0;
24232470 }
24242471

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t