Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'probes-fixes-v6.12-rc4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull probes fixes from Masami Hiramatsu:

- objpool: Fix choosing allocation for percpu slots

Fixes to allocate objpool's percpu slots correctly according to the
GFP flag. It checks whether "any bit" in GFP_ATOMIC is set to choose
the vmalloc source, but it should check "all bits" in GFP_ATOMIC flag
is set, because GFP_ATOMIC is a combined flag.

- tracing/probes: Fix MAX_TRACE_ARGS limit handling

If more than MAX_TRACE_ARGS are passed for creating a probe event,
the entries over MAX_TRACE_ARG in trace_arg array are not
initialized. Thus if the kernel accesses those entries, it crashes.
This rejects creating event if the number of arguments is over
MAX_TRACE_ARGS.

- tracing: Consider the NUL character when validating the event length

A strlen() is used when parsing the event name, and the original code
does not consider the terminal null byte. Thus it can pass the name
one byte longer than the buffer. This fixes to check it correctly.

* tag 'probes-fixes-v6.12-rc4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
tracing: Consider the NULL character when validating the event length
tracing/probes: Fix MAX_TRACE_ARGS limit handling
objpool: fix choosing allocation for percpu slots

+21 -6
+6 -1
kernel/trace/trace_eprobe.c
··· 912 912 } 913 913 } 914 914 915 + if (argc - 2 > MAX_TRACE_ARGS) { 916 + ret = -E2BIG; 917 + goto error; 918 + } 919 + 915 920 mutex_lock(&event_mutex); 916 921 event_call = find_and_get_event(sys_name, sys_event); 917 922 ep = alloc_event_probe(group, event, event_call, argc - 2); ··· 942 937 943 938 argc -= 2; argv += 2; 944 939 /* parse arguments */ 945 - for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) { 940 + for (i = 0; i < argc; i++) { 946 941 trace_probe_log_set_index(i + 2); 947 942 ret = trace_eprobe_tp_update_arg(ep, argv, i); 948 943 if (ret)
+5 -1
kernel/trace/trace_fprobe.c
··· 1187 1187 argc = new_argc; 1188 1188 argv = new_argv; 1189 1189 } 1190 + if (argc > MAX_TRACE_ARGS) { 1191 + ret = -E2BIG; 1192 + goto out; 1193 + } 1190 1194 1191 1195 ret = traceprobe_expand_dentry_args(argc, argv, &dbuf); 1192 1196 if (ret) ··· 1207 1203 } 1208 1204 1209 1205 /* parse arguments */ 1210 - for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) { 1206 + for (i = 0; i < argc; i++) { 1211 1207 trace_probe_log_set_index(i + 2); 1212 1208 ctx.offset = 0; 1213 1209 ret = traceprobe_parse_probe_arg(&tf->tp, i, argv[i], &ctx);
+5 -1
kernel/trace/trace_kprobe.c
··· 1013 1013 argc = new_argc; 1014 1014 argv = new_argv; 1015 1015 } 1016 + if (argc > MAX_TRACE_ARGS) { 1017 + ret = -E2BIG; 1018 + goto out; 1019 + } 1016 1020 1017 1021 ret = traceprobe_expand_dentry_args(argc, argv, &dbuf); 1018 1022 if (ret) ··· 1033 1029 } 1034 1030 1035 1031 /* parse arguments */ 1036 - for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) { 1032 + for (i = 0; i < argc; i++) { 1037 1033 trace_probe_log_set_index(i + 2); 1038 1034 ctx.offset = 0; 1039 1035 ret = traceprobe_parse_probe_arg(&tk->tp, i, argv[i], &ctx);
+1 -1
kernel/trace/trace_probe.c
··· 276 276 } 277 277 trace_probe_log_err(offset, NO_EVENT_NAME); 278 278 return -EINVAL; 279 - } else if (len > MAX_EVENT_NAME_LEN) { 279 + } else if (len >= MAX_EVENT_NAME_LEN) { 280 280 trace_probe_log_err(offset, EVENT_TOO_LONG); 281 281 return -EINVAL; 282 282 }
+3 -1
kernel/trace/trace_uprobe.c
··· 565 565 566 566 if (argc < 2) 567 567 return -ECANCELED; 568 + if (argc - 2 > MAX_TRACE_ARGS) 569 + return -E2BIG; 568 570 569 571 if (argv[0][1] == ':') 570 572 event = &argv[0][2]; ··· 692 690 tu->filename = filename; 693 691 694 692 /* parse arguments */ 695 - for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) { 693 + for (i = 0; i < argc; i++) { 696 694 struct traceprobe_parse_context ctx = { 697 695 .flags = (is_return ? TPARG_FL_RETURN : 0) | TPARG_FL_USER, 698 696 };
+1 -1
lib/objpool.c
··· 76 76 * mimimal size of vmalloc is one page since vmalloc would 77 77 * always align the requested size to page size 78 78 */ 79 - if (pool->gfp & GFP_ATOMIC) 79 + if ((pool->gfp & GFP_ATOMIC) == GFP_ATOMIC) 80 80 slot = kmalloc_node(size, pool->gfp, cpu_to_node(i)); 81 81 else 82 82 slot = __vmalloc_node(size, sizeof(void *), pool->gfp,