Skip to content

Commit

Permalink
Merge tag 'trace-v5.10-rc1' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/rostedt/linux-trace

Pull tracing fix from Steven Rostedt:
 "Fix synthetic event "strcat" overrun

  New synthetic event code used strcat() and miscalculated the ending,
  causing the concatenation to write beyond the allocated memory.

  Instead of using strncat(), the code is switched over to seq_buf which
  has all the mechanisms in place to protect against writing more than
  what is allocated, and cleans up the code a bit"

* tag 'trace-v5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
  tracing, synthetic events: Replace buggy strcat() with seq_buf operations
  • Loading branch information
torvalds committed Oct 28, 2020
2 parents ed8780e + 761a8c5 commit 23859ae
Showing 1 changed file with 22 additions and 14 deletions.
36 changes: 22 additions & 14 deletions kernel/trace/trace_events_synth.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,7 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
struct synth_field *field;
const char *prefix = NULL, *field_type = argv[0], *field_name, *array;
int len, ret = 0;
struct seq_buf s;
ssize_t size;

if (field_type[0] == ';')
Expand Down Expand Up @@ -630,13 +631,9 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
field_type++;
len = strlen(field_type) + 1;

if (array) {
int l = strlen(array);
if (array)
len += strlen(array);

if (l && array[l - 1] == ';')
l--;
len += l;
}
if (prefix)
len += strlen(prefix);

Expand All @@ -645,14 +642,18 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
ret = -ENOMEM;
goto free;
}
seq_buf_init(&s, field->type, len);
if (prefix)
strcat(field->type, prefix);
strcat(field->type, field_type);
seq_buf_puts(&s, prefix);
seq_buf_puts(&s, field_type);
if (array) {
strcat(field->type, array);
if (field->type[len - 1] == ';')
field->type[len - 1] = '\0';
seq_buf_puts(&s, array);
if (s.buffer[s.len - 1] == ';')
s.len--;
}
if (WARN_ON_ONCE(!seq_buf_buffer_left(&s)))
goto free;
s.buffer[s.len] = '\0';

size = synth_field_size(field->type);
if (size < 0) {
Expand All @@ -663,14 +664,21 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
if (synth_field_is_string(field->type)) {
char *type;

type = kzalloc(sizeof("__data_loc ") + strlen(field->type) + 1, GFP_KERNEL);
len = sizeof("__data_loc ") + strlen(field->type) + 1;
type = kzalloc(len, GFP_KERNEL);
if (!type) {
ret = -ENOMEM;
goto free;
}

strcat(type, "__data_loc ");
strcat(type, field->type);
seq_buf_init(&s, type, len);
seq_buf_puts(&s, "__data_loc ");
seq_buf_puts(&s, field->type);

if (WARN_ON_ONCE(!seq_buf_buffer_left(&s)))
goto free;
s.buffer[s.len] = '\0';

kfree(field->type);
field->type = type;

Expand Down

0 comments on commit 23859ae

Please sign in to comment.