Skip to content

Commit 25a1298

Browse files
committed
Merge tag 'trace-v5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing fix from Steven Rostedt: "Fix trace_check_vprintf() for %.*s The sanity check of all strings being read from the ring buffer to make sure they are in safe memory space did not account for the %.*s notation having another parameter to process (the length). Add that to the check" * tag 'trace-v5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: tracing: Handle %.*s in trace_check_vprintf()
2 parents bd3c9cd + eb01f53 commit 25a1298

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

kernel/trace/trace.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3704,6 +3704,9 @@ void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
37043704
goto print;
37053705

37063706
while (*p) {
3707+
bool star = false;
3708+
int len = 0;
3709+
37073710
j = 0;
37083711

37093712
/* We only care about %s and variants */
@@ -3725,13 +3728,17 @@ void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
37253728
/* Need to test cases like %08.*s */
37263729
for (j = 1; p[i+j]; j++) {
37273730
if (isdigit(p[i+j]) ||
3728-
p[i+j] == '*' ||
37293731
p[i+j] == '.')
37303732
continue;
3733+
if (p[i+j] == '*') {
3734+
star = true;
3735+
continue;
3736+
}
37313737
break;
37323738
}
37333739
if (p[i+j] == 's')
37343740
break;
3741+
star = false;
37353742
}
37363743
j = 0;
37373744
}
@@ -3744,6 +3751,9 @@ void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
37443751
iter->fmt[i] = '\0';
37453752
trace_seq_vprintf(&iter->seq, iter->fmt, ap);
37463753

3754+
if (star)
3755+
len = va_arg(ap, int);
3756+
37473757
/* The ap now points to the string data of the %s */
37483758
str = va_arg(ap, const char *);
37493759

@@ -3762,8 +3772,18 @@ void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
37623772
int ret;
37633773

37643774
/* Try to safely read the string */
3765-
ret = strncpy_from_kernel_nofault(iter->fmt, str,
3766-
iter->fmt_size);
3775+
if (star) {
3776+
if (len + 1 > iter->fmt_size)
3777+
len = iter->fmt_size - 1;
3778+
if (len < 0)
3779+
len = 0;
3780+
ret = copy_from_kernel_nofault(iter->fmt, str, len);
3781+
iter->fmt[len] = 0;
3782+
star = false;
3783+
} else {
3784+
ret = strncpy_from_kernel_nofault(iter->fmt, str,
3785+
iter->fmt_size);
3786+
}
37673787
if (ret < 0)
37683788
trace_seq_printf(&iter->seq, "(0x%px)", str);
37693789
else
@@ -3775,7 +3795,10 @@ void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
37753795
strncpy(iter->fmt, p + i, j + 1);
37763796
iter->fmt[j+1] = '\0';
37773797
}
3778-
trace_seq_printf(&iter->seq, iter->fmt, str);
3798+
if (star)
3799+
trace_seq_printf(&iter->seq, iter->fmt, len, str);
3800+
else
3801+
trace_seq_printf(&iter->seq, iter->fmt, str);
37793802

37803803
p += i + j + 1;
37813804
}

0 commit comments

Comments
 (0)