diff options
-rw-r--r-- | kernel/trace/trace_kprobe.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 7ecab06547a5..375f81a568dc 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -282,6 +282,18 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs); | |||
282 | static int kretprobe_dispatcher(struct kretprobe_instance *ri, | 282 | static int kretprobe_dispatcher(struct kretprobe_instance *ri, |
283 | struct pt_regs *regs); | 283 | struct pt_regs *regs); |
284 | 284 | ||
285 | /* Check the name is good for event/group */ | ||
286 | static int check_event_name(const char *name) | ||
287 | { | ||
288 | if (!isalpha(*name) && *name != '_') | ||
289 | return 0; | ||
290 | while (*++name != '\0') { | ||
291 | if (!isalpha(*name) && !isdigit(*name) && *name != '_') | ||
292 | return 0; | ||
293 | } | ||
294 | return 1; | ||
295 | } | ||
296 | |||
285 | /* | 297 | /* |
286 | * Allocate new trace_probe and initialize it (including kprobes). | 298 | * Allocate new trace_probe and initialize it (including kprobes). |
287 | */ | 299 | */ |
@@ -293,10 +305,11 @@ static struct trace_probe *alloc_trace_probe(const char *group, | |||
293 | int nargs, int is_return) | 305 | int nargs, int is_return) |
294 | { | 306 | { |
295 | struct trace_probe *tp; | 307 | struct trace_probe *tp; |
308 | int ret = -ENOMEM; | ||
296 | 309 | ||
297 | tp = kzalloc(SIZEOF_TRACE_PROBE(nargs), GFP_KERNEL); | 310 | tp = kzalloc(SIZEOF_TRACE_PROBE(nargs), GFP_KERNEL); |
298 | if (!tp) | 311 | if (!tp) |
299 | return ERR_PTR(-ENOMEM); | 312 | return ERR_PTR(ret); |
300 | 313 | ||
301 | if (symbol) { | 314 | if (symbol) { |
302 | tp->symbol = kstrdup(symbol, GFP_KERNEL); | 315 | tp->symbol = kstrdup(symbol, GFP_KERNEL); |
@@ -312,14 +325,20 @@ static struct trace_probe *alloc_trace_probe(const char *group, | |||
312 | else | 325 | else |
313 | tp->rp.kp.pre_handler = kprobe_dispatcher; | 326 | tp->rp.kp.pre_handler = kprobe_dispatcher; |
314 | 327 | ||
315 | if (!event) | 328 | if (!event || !check_event_name(event)) { |
329 | ret = -EINVAL; | ||
316 | goto error; | 330 | goto error; |
331 | } | ||
332 | |||
317 | tp->call.name = kstrdup(event, GFP_KERNEL); | 333 | tp->call.name = kstrdup(event, GFP_KERNEL); |
318 | if (!tp->call.name) | 334 | if (!tp->call.name) |
319 | goto error; | 335 | goto error; |
320 | 336 | ||
321 | if (!group) | 337 | if (!group || !check_event_name(group)) { |
338 | ret = -EINVAL; | ||
322 | goto error; | 339 | goto error; |
340 | } | ||
341 | |||
323 | tp->call.system = kstrdup(group, GFP_KERNEL); | 342 | tp->call.system = kstrdup(group, GFP_KERNEL); |
324 | if (!tp->call.system) | 343 | if (!tp->call.system) |
325 | goto error; | 344 | goto error; |
@@ -330,7 +349,7 @@ error: | |||
330 | kfree(tp->call.name); | 349 | kfree(tp->call.name); |
331 | kfree(tp->symbol); | 350 | kfree(tp->symbol); |
332 | kfree(tp); | 351 | kfree(tp); |
333 | return ERR_PTR(-ENOMEM); | 352 | return ERR_PTR(ret); |
334 | } | 353 | } |
335 | 354 | ||
336 | static void free_probe_arg(struct probe_arg *arg) | 355 | static void free_probe_arg(struct probe_arg *arg) |
@@ -695,10 +714,10 @@ static int create_trace_probe(int argc, char **argv) | |||
695 | if (!event) { | 714 | if (!event) { |
696 | /* Make a new event name */ | 715 | /* Make a new event name */ |
697 | if (symbol) | 716 | if (symbol) |
698 | snprintf(buf, MAX_EVENT_NAME_LEN, "%c@%s%+ld", | 717 | snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_%ld", |
699 | is_return ? 'r' : 'p', symbol, offset); | 718 | is_return ? 'r' : 'p', symbol, offset); |
700 | else | 719 | else |
701 | snprintf(buf, MAX_EVENT_NAME_LEN, "%c@0x%p", | 720 | snprintf(buf, MAX_EVENT_NAME_LEN, "%c_0x%p", |
702 | is_return ? 'r' : 'p', addr); | 721 | is_return ? 'r' : 'p', addr); |
703 | event = buf; | 722 | event = buf; |
704 | } | 723 | } |