Skip to content

Commit fcd9db5

Browse files
committed
tracing/probe: Have traceprobe_parse_probe_arg() take a const arg
The two places that call traceprobe_parse_probe_arg() allocate a temporary buffer to copy the argv[i] into, because argv[i] is constant and the traceprobe_parse_probe_arg() will modify it to do the parsing. These two places allocate this buffer and then free it right after calling this function, leaving the onus of this allocation to the caller. As there's about to be a third user of this function that will have to do the same thing, instead of having the caller allocate the temporary buffer, simply move that allocation into the traceprobe_parse_probe_arg() itself, which will simplify the code of the callers. Link: https://lkml.kernel.org/r/[email protected] Acked-by: Masami Hiramatsu <[email protected]> Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent 1d18538 commit fcd9db5

File tree

4 files changed

+31
-36
lines changed

4 files changed

+31
-36
lines changed

kernel/trace/trace_kprobe.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -873,15 +873,8 @@ static int __trace_kprobe_create(int argc, const char *argv[])
873873

874874
/* parse arguments */
875875
for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
876-
tmp = kstrdup(argv[i], GFP_KERNEL);
877-
if (!tmp) {
878-
ret = -ENOMEM;
879-
goto error;
880-
}
881-
882876
trace_probe_log_set_index(i + 2);
883-
ret = traceprobe_parse_probe_arg(&tk->tp, i, tmp, flags);
884-
kfree(tmp);
877+
ret = traceprobe_parse_probe_arg(&tk->tp, i, argv[i], flags);
885878
if (ret)
886879
goto error; /* This can be -ENOMEM */
887880
}

kernel/trace/trace_probe.c

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -540,26 +540,34 @@ static int __parse_bitfield_probe_arg(const char *bf,
540540
}
541541

542542
/* String length checking wrapper */
543-
static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
543+
static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
544544
struct probe_arg *parg, unsigned int flags, int offset)
545545
{
546546
struct fetch_insn *code, *scode, *tmp = NULL;
547547
char *t, *t2, *t3;
548+
char *arg;
548549
int ret, len;
549550

551+
arg = kstrdup(argv, GFP_KERNEL);
552+
if (!arg)
553+
return -ENOMEM;
554+
555+
ret = -EINVAL;
550556
len = strlen(arg);
551557
if (len > MAX_ARGSTR_LEN) {
552558
trace_probe_log_err(offset, ARG_TOO_LONG);
553-
return -EINVAL;
559+
goto out;
554560
} else if (len == 0) {
555561
trace_probe_log_err(offset, NO_ARG_BODY);
556-
return -EINVAL;
562+
goto out;
557563
}
558564

565+
ret = -ENOMEM;
559566
parg->comm = kstrdup(arg, GFP_KERNEL);
560567
if (!parg->comm)
561-
return -ENOMEM;
568+
goto out;
562569

570+
ret = -EINVAL;
563571
t = strchr(arg, ':');
564572
if (t) {
565573
*t = '\0';
@@ -571,22 +579,22 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
571579
offset += t2 + strlen(t2) - arg;
572580
trace_probe_log_err(offset,
573581
ARRAY_NO_CLOSE);
574-
return -EINVAL;
582+
goto out;
575583
} else if (t3[1] != '\0') {
576584
trace_probe_log_err(offset + t3 + 1 - arg,
577585
BAD_ARRAY_SUFFIX);
578-
return -EINVAL;
586+
goto out;
579587
}
580588
*t3 = '\0';
581589
if (kstrtouint(t2, 0, &parg->count) || !parg->count) {
582590
trace_probe_log_err(offset + t2 - arg,
583591
BAD_ARRAY_NUM);
584-
return -EINVAL;
592+
goto out;
585593
}
586594
if (parg->count > MAX_ARRAY_LEN) {
587595
trace_probe_log_err(offset + t2 - arg,
588596
ARRAY_TOO_BIG);
589-
return -EINVAL;
597+
goto out;
590598
}
591599
}
592600
}
@@ -598,36 +606,38 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
598606
if (strcmp(arg, "$comm") == 0 || strncmp(arg, "\\\"", 2) == 0) {
599607
/* The type of $comm must be "string", and not an array. */
600608
if (parg->count || (t && strcmp(t, "string")))
601-
return -EINVAL;
609+
goto out;
602610
parg->type = find_fetch_type("string");
603611
} else
604612
parg->type = find_fetch_type(t);
605613
if (!parg->type) {
606614
trace_probe_log_err(offset + (t ? (t - arg) : 0), BAD_TYPE);
607-
return -EINVAL;
615+
goto out;
608616
}
609617
parg->offset = *size;
610618
*size += parg->type->size * (parg->count ?: 1);
611619

620+
ret = -ENOMEM;
612621
if (parg->count) {
613622
len = strlen(parg->type->fmttype) + 6;
614623
parg->fmt = kmalloc(len, GFP_KERNEL);
615624
if (!parg->fmt)
616-
return -ENOMEM;
625+
goto out;
617626
snprintf(parg->fmt, len, "%s[%d]", parg->type->fmttype,
618627
parg->count);
619628
}
620629

621630
code = tmp = kcalloc(FETCH_INSN_MAX, sizeof(*code), GFP_KERNEL);
622631
if (!code)
623-
return -ENOMEM;
632+
goto out;
624633
code[FETCH_INSN_MAX - 1].op = FETCH_OP_END;
625634

626635
ret = parse_probe_arg(arg, parg->type, &code, &code[FETCH_INSN_MAX - 1],
627636
flags, offset);
628637
if (ret)
629638
goto fail;
630639

640+
ret = -EINVAL;
631641
/* Store operation */
632642
if (!strcmp(parg->type->name, "string") ||
633643
!strcmp(parg->type->name, "ustring")) {
@@ -636,7 +646,6 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
636646
code->op != FETCH_OP_DATA) {
637647
trace_probe_log_err(offset + (t ? (t - arg) : 0),
638648
BAD_STRING);
639-
ret = -EINVAL;
640649
goto fail;
641650
}
642651
if ((code->op == FETCH_OP_IMM || code->op == FETCH_OP_COMM ||
@@ -650,7 +659,6 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
650659
code++;
651660
if (code->op != FETCH_OP_NOP) {
652661
trace_probe_log_err(offset, TOO_MANY_OPS);
653-
ret = -EINVAL;
654662
goto fail;
655663
}
656664
}
@@ -672,7 +680,6 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
672680
code++;
673681
if (code->op != FETCH_OP_NOP) {
674682
trace_probe_log_err(offset, TOO_MANY_OPS);
675-
ret = -EINVAL;
676683
goto fail;
677684
}
678685
code->op = FETCH_OP_ST_RAW;
@@ -687,20 +694,19 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
687694
goto fail;
688695
}
689696
}
697+
ret = -EINVAL;
690698
/* Loop(Array) operation */
691699
if (parg->count) {
692700
if (scode->op != FETCH_OP_ST_MEM &&
693701
scode->op != FETCH_OP_ST_STRING &&
694702
scode->op != FETCH_OP_ST_USTRING) {
695703
trace_probe_log_err(offset + (t ? (t - arg) : 0),
696704
BAD_STRING);
697-
ret = -EINVAL;
698705
goto fail;
699706
}
700707
code++;
701708
if (code->op != FETCH_OP_NOP) {
702709
trace_probe_log_err(offset, TOO_MANY_OPS);
703-
ret = -EINVAL;
704710
goto fail;
705711
}
706712
code->op = FETCH_OP_LP_ARRAY;
@@ -709,6 +715,7 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
709715
code++;
710716
code->op = FETCH_OP_END;
711717

718+
ret = 0;
712719
/* Shrink down the code buffer */
713720
parg->code = kcalloc(code - tmp + 1, sizeof(*code), GFP_KERNEL);
714721
if (!parg->code)
@@ -724,6 +731,8 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
724731
kfree(code->data);
725732
}
726733
kfree(tmp);
734+
out:
735+
kfree(arg);
727736

728737
return ret;
729738
}
@@ -745,11 +754,11 @@ static int traceprobe_conflict_field_name(const char *name,
745754
return 0;
746755
}
747756

748-
int traceprobe_parse_probe_arg(struct trace_probe *tp, int i, char *arg,
757+
int traceprobe_parse_probe_arg(struct trace_probe *tp, int i, const char *arg,
749758
unsigned int flags)
750759
{
751760
struct probe_arg *parg = &tp->args[i];
752-
char *body;
761+
const char *body;
753762

754763
/* Increment count for freeing args in error case */
755764
tp->nr_args++;

kernel/trace/trace_probe.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ int trace_probe_create(const char *raw_command, int (*createfn)(int, const char
354354
#define TPARG_FL_MASK GENMASK(2, 0)
355355

356356
extern int traceprobe_parse_probe_arg(struct trace_probe *tp, int i,
357-
char *arg, unsigned int flags);
357+
const char *argv, unsigned int flags);
358358

359359
extern int traceprobe_update_arg(struct probe_arg *arg);
360360
extern void traceprobe_free_probe_arg(struct probe_arg *arg);

kernel/trace/trace_uprobe.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -684,16 +684,9 @@ static int __trace_uprobe_create(int argc, const char **argv)
684684

685685
/* parse arguments */
686686
for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
687-
tmp = kstrdup(argv[i], GFP_KERNEL);
688-
if (!tmp) {
689-
ret = -ENOMEM;
690-
goto error;
691-
}
692-
693687
trace_probe_log_set_index(i + 2);
694-
ret = traceprobe_parse_probe_arg(&tu->tp, i, tmp,
688+
ret = traceprobe_parse_probe_arg(&tu->tp, i, argv[i],
695689
is_return ? TPARG_FL_RETURN : 0);
696-
kfree(tmp);
697690
if (ret)
698691
goto error;
699692
}

0 commit comments

Comments
 (0)