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.

tracing: uprobes: Cleanup __trace_uprobe_create() with __free()

Use __free() to cleanup ugly gotos in __trace_uprobe_create().

Link: https://lore.kernel.org/all/175509540482.193596.6541098946023873304.stgit@devnote2/

Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>

+26 -42
+26 -42
kernel/trace/trace_uprobe.c
··· 533 533 return ret; 534 534 } 535 535 536 + DEFINE_FREE(free_trace_uprobe, struct trace_uprobe *, if (_T) free_trace_uprobe(_T)) 537 + 536 538 /* 537 539 * Argument syntax: 538 540 * - Add uprobe: p|r[:[GRP/][EVENT]] PATH:OFFSET[%return][(REF)] [FETCHARGS] 539 541 */ 540 542 static int __trace_uprobe_create(int argc, const char **argv) 541 543 { 544 + struct trace_uprobe *tu __free(free_trace_uprobe) = NULL; 542 545 const char *trlog __free(trace_probe_log_clear) = NULL; 543 546 const char *event = NULL, *group = UPROBE_EVENT_SYSTEM; 544 - char *arg, *filename, *rctr, *rctr_end, *tmp; 547 + struct path path __free(path_put) = {}; 545 548 unsigned long offset, ref_ctr_offset; 549 + char *filename __free(kfree) = NULL; 550 + char *arg, *rctr, *rctr_end, *tmp; 546 551 char *gbuf __free(kfree) = NULL; 547 552 char *buf __free(kfree) = NULL; 548 553 enum probe_print_type ptype; 549 - struct trace_uprobe *tu; 550 554 bool is_return = false; 551 - struct path path; 552 555 int i, ret; 553 556 554 557 ref_ctr_offset = 0; ··· 589 586 590 587 /* Find the last occurrence, in case the path contains ':' too. */ 591 588 arg = strrchr(filename, ':'); 592 - if (!arg || !isdigit(arg[1])) { 593 - kfree(filename); 589 + if (!arg || !isdigit(arg[1])) 594 590 return -ECANCELED; 595 - } 596 591 597 592 trace_probe_log_set_index(1); /* filename is the 2nd argument */ 598 593 ··· 598 597 ret = kern_path(filename, LOOKUP_FOLLOW, &path); 599 598 if (ret) { 600 599 trace_probe_log_err(0, FILE_NOT_FOUND); 601 - kfree(filename); 602 600 return ret; 603 601 } 604 602 if (!d_is_reg(path.dentry)) { 605 603 trace_probe_log_err(0, NO_REGULAR_FILE); 606 - ret = -EINVAL; 607 - goto fail_address_parse; 604 + return -EINVAL; 608 605 } 609 606 610 607 /* Parse reference counter offset if specified. */ ··· 610 611 if (rctr) { 611 612 rctr_end = strchr(rctr, ')'); 612 613 if (!rctr_end) { 613 - ret = -EINVAL; 614 614 rctr_end = rctr + strlen(rctr); 615 615 trace_probe_log_err(rctr_end - filename, 616 616 REFCNT_OPEN_BRACE); 617 - goto fail_address_parse; 617 + return -EINVAL; 618 618 } else if (rctr_end[1] != '\0') { 619 - ret = -EINVAL; 620 619 trace_probe_log_err(rctr_end + 1 - filename, 621 620 BAD_REFCNT_SUFFIX); 622 - goto fail_address_parse; 621 + return -EINVAL; 623 622 } 624 623 625 624 *rctr++ = '\0'; ··· 625 628 ret = kstrtoul(rctr, 0, &ref_ctr_offset); 626 629 if (ret) { 627 630 trace_probe_log_err(rctr - filename, BAD_REFCNT); 628 - goto fail_address_parse; 631 + return ret; 629 632 } 630 633 } 631 634 ··· 637 640 is_return = true; 638 641 } else { 639 642 trace_probe_log_err(tmp - filename, BAD_ADDR_SUFFIX); 640 - ret = -EINVAL; 641 - goto fail_address_parse; 643 + return -EINVAL; 642 644 } 643 645 } 644 646 ··· 645 649 ret = kstrtoul(arg, 0, &offset); 646 650 if (ret) { 647 651 trace_probe_log_err(arg - filename, BAD_UPROBE_OFFS); 648 - goto fail_address_parse; 652 + return ret; 649 653 } 650 654 651 655 /* setup a probe */ ··· 653 657 if (event) { 654 658 gbuf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL); 655 659 if (!gbuf) 656 - goto fail_mem; 660 + return -ENOMEM; 657 661 658 662 ret = traceprobe_parse_event_name(&event, &group, gbuf, 659 663 event - argv[0]); 660 664 if (ret) 661 - goto fail_address_parse; 665 + return ret; 662 666 } 663 667 664 668 if (!event) { ··· 667 671 668 672 tail = kstrdup(kbasename(filename), GFP_KERNEL); 669 673 if (!tail) 670 - goto fail_mem; 674 + return -ENOMEM; 671 675 672 676 ptr = strpbrk(tail, ".-_"); 673 677 if (ptr) ··· 675 679 676 680 buf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL); 677 681 if (!buf) 678 - goto fail_mem; 682 + return -ENOMEM; 679 683 snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_0x%lx", 'p', tail, offset); 680 684 event = buf; 681 685 kfree(tail); ··· 689 693 ret = PTR_ERR(tu); 690 694 /* This must return -ENOMEM otherwise there is a bug */ 691 695 WARN_ON_ONCE(ret != -ENOMEM); 692 - goto fail_address_parse; 696 + return ret; 693 697 } 694 698 tu->offset = offset; 695 699 tu->ref_ctr_offset = ref_ctr_offset; 696 700 tu->path = path; 697 - tu->filename = filename; 701 + /* Clear @path so that it will not freed by path_put() */ 702 + memset(&path, 0, sizeof(path)); 703 + tu->filename = no_free_ptr(filename); 698 704 699 705 /* parse arguments */ 700 706 for (i = 0; i < argc; i++) { 701 707 struct traceprobe_parse_context *ctx __free(traceprobe_parse_context) 702 708 = kzalloc(sizeof(*ctx), GFP_KERNEL); 703 709 704 - if (!ctx) { 705 - ret = -ENOMEM; 706 - goto error; 707 - } 710 + if (!ctx) 711 + return -ENOMEM; 708 712 ctx->flags = (is_return ? TPARG_FL_RETURN : 0) | TPARG_FL_USER; 709 713 trace_probe_log_set_index(i + 2); 710 714 ret = traceprobe_parse_probe_arg(&tu->tp, i, argv[i], ctx); 711 715 if (ret) 712 - goto error; 716 + return ret; 713 717 } 714 718 715 719 ptype = is_ret_probe(tu) ? PROBE_PRINT_RETURN : PROBE_PRINT_NORMAL; 716 720 ret = traceprobe_set_print_fmt(&tu->tp, ptype); 717 721 if (ret < 0) 718 - goto error; 722 + return ret; 719 723 720 724 ret = register_trace_uprobe(tu); 721 725 if (!ret) 722 - goto out; 723 - 724 - error: 725 - free_trace_uprobe(tu); 726 - out: 727 - return ret; 728 - 729 - fail_mem: 730 - ret = -ENOMEM; 731 - 732 - fail_address_parse: 733 - path_put(&path); 734 - kfree(filename); 726 + tu = NULL; 735 727 736 728 return ret; 737 729 }