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 'trace-v6.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull `lTracing fixes for 6.1-rc3:

- Fixed NULL pointer dereference in the ring buffer wait-waiters code
for machines that have less CPUs than what nr_cpu_ids returns.

The buffer array is of size nr_cpu_ids, but only the online CPUs get
initialized.

- Fixed use after free call in ftrace_shutdown.

- Fix accounting of if a kprobe is enabled

- Fix NULL pointer dereference on error path of fprobe rethook_alloc().

- Fix unregistering of fprobe_kprobe_handler

- Fix memory leak in kprobe test module

* tag 'trace-v6.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
tracing: kprobe: Fix memory leak in test_gen_kprobe/kretprobe_cmd()
tracing/fprobe: Fix to check whether fprobe is registered correctly
fprobe: Check rethook_alloc() return in rethook initialization
kprobe: reverse kp->flags when arm_kprobe failed
ftrace: Fix use-after-free for dynamic ftrace_ops
ring-buffer: Check for NULL cpu_buffer in ring_buffer_wake_waiters()

+29 -26
+4 -1
kernel/kprobes.c
··· 2429 2429 if (!kprobes_all_disarmed && kprobe_disabled(p)) { 2430 2430 p->flags &= ~KPROBE_FLAG_DISABLED; 2431 2431 ret = arm_kprobe(p); 2432 - if (ret) 2432 + if (ret) { 2433 2433 p->flags |= KPROBE_FLAG_DISABLED; 2434 + if (p != kp) 2435 + kp->flags |= KPROBE_FLAG_DISABLED; 2436 + } 2434 2437 } 2435 2438 out: 2436 2439 mutex_unlock(&kprobe_mutex);
+4 -1
kernel/trace/fprobe.c
··· 141 141 return -E2BIG; 142 142 143 143 fp->rethook = rethook_alloc((void *)fp, fprobe_exit_handler); 144 + if (!fp->rethook) 145 + return -ENOMEM; 144 146 for (i = 0; i < size; i++) { 145 147 struct fprobe_rethook_node *node; 146 148 ··· 303 301 { 304 302 int ret; 305 303 306 - if (!fp || fp->ops.func != fprobe_handler) 304 + if (!fp || (fp->ops.saved_func != fprobe_handler && 305 + fp->ops.saved_func != fprobe_kprobe_handler)) 307 306 return -EINVAL; 308 307 309 308 /*
+3 -13
kernel/trace/ftrace.c
··· 3028 3028 command |= FTRACE_UPDATE_TRACE_FUNC; 3029 3029 } 3030 3030 3031 - if (!command || !ftrace_enabled) { 3032 - /* 3033 - * If these are dynamic or per_cpu ops, they still 3034 - * need their data freed. Since, function tracing is 3035 - * not currently active, we can just free them 3036 - * without synchronizing all CPUs. 3037 - */ 3038 - if (ops->flags & FTRACE_OPS_FL_DYNAMIC) 3039 - goto free_ops; 3040 - 3041 - return 0; 3042 - } 3031 + if (!command || !ftrace_enabled) 3032 + goto out; 3043 3033 3044 3034 /* 3045 3035 * If the ops uses a trampoline, then it needs to be ··· 3066 3076 removed_ops = NULL; 3067 3077 ops->flags &= ~FTRACE_OPS_FL_REMOVING; 3068 3078 3079 + out: 3069 3080 /* 3070 3081 * Dynamic ops may be freed, we must make sure that all 3071 3082 * callers are done before leaving this function. ··· 3094 3103 if (IS_ENABLED(CONFIG_PREEMPTION)) 3095 3104 synchronize_rcu_tasks(); 3096 3105 3097 - free_ops: 3098 3106 ftrace_trampoline_free(ops); 3099 3107 } 3100 3108
+7 -11
kernel/trace/kprobe_event_gen_test.c
··· 100 100 KPROBE_GEN_TEST_FUNC, 101 101 KPROBE_GEN_TEST_ARG0, KPROBE_GEN_TEST_ARG1); 102 102 if (ret) 103 - goto free; 103 + goto out; 104 104 105 105 /* Use kprobe_event_add_fields to add the rest of the fields */ 106 106 107 107 ret = kprobe_event_add_fields(&cmd, KPROBE_GEN_TEST_ARG2, KPROBE_GEN_TEST_ARG3); 108 108 if (ret) 109 - goto free; 109 + goto out; 110 110 111 111 /* 112 112 * This actually creates the event. 113 113 */ 114 114 ret = kprobe_event_gen_cmd_end(&cmd); 115 115 if (ret) 116 - goto free; 116 + goto out; 117 117 118 118 /* 119 119 * Now get the gen_kprobe_test event file. We need to prevent ··· 136 136 goto delete; 137 137 } 138 138 out: 139 + kfree(buf); 139 140 return ret; 140 141 delete: 141 142 /* We got an error after creating the event, delete it */ 142 143 ret = kprobe_event_delete("gen_kprobe_test"); 143 - free: 144 - kfree(buf); 145 - 146 144 goto out; 147 145 } 148 146 ··· 168 170 KPROBE_GEN_TEST_FUNC, 169 171 "$retval"); 170 172 if (ret) 171 - goto free; 173 + goto out; 172 174 173 175 /* 174 176 * This actually creates the event. 175 177 */ 176 178 ret = kretprobe_event_gen_cmd_end(&cmd); 177 179 if (ret) 178 - goto free; 180 + goto out; 179 181 180 182 /* 181 183 * Now get the gen_kretprobe_test event file. We need to ··· 199 201 goto delete; 200 202 } 201 203 out: 204 + kfree(buf); 202 205 return ret; 203 206 delete: 204 207 /* We got an error after creating the event, delete it */ 205 208 ret = kprobe_event_delete("gen_kretprobe_test"); 206 - free: 207 - kfree(buf); 208 - 209 209 goto out; 210 210 } 211 211
+11
kernel/trace/ring_buffer.c
··· 937 937 struct ring_buffer_per_cpu *cpu_buffer; 938 938 struct rb_irq_work *rbwork; 939 939 940 + if (!buffer) 941 + return; 942 + 940 943 if (cpu == RING_BUFFER_ALL_CPUS) { 941 944 942 945 /* Wake up individual ones too. One level recursion */ ··· 948 945 949 946 rbwork = &buffer->irq_work; 950 947 } else { 948 + if (WARN_ON_ONCE(!buffer->buffers)) 949 + return; 950 + if (WARN_ON_ONCE(cpu >= nr_cpu_ids)) 951 + return; 952 + 951 953 cpu_buffer = buffer->buffers[cpu]; 954 + /* The CPU buffer may not have been initialized yet */ 955 + if (!cpu_buffer) 956 + return; 952 957 rbwork = &cpu_buffer->irq_work; 953 958 } 954 959