Commit 23859ae4 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'trace-v5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/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
parents ed8780e3 761a8c58
...@@ -585,6 +585,7 @@ static struct synth_field *parse_synth_field(int argc, const char **argv, ...@@ -585,6 +585,7 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
struct synth_field *field; struct synth_field *field;
const char *prefix = NULL, *field_type = argv[0], *field_name, *array; const char *prefix = NULL, *field_type = argv[0], *field_name, *array;
int len, ret = 0; int len, ret = 0;
struct seq_buf s;
ssize_t size; ssize_t size;
if (field_type[0] == ';') if (field_type[0] == ';')
...@@ -630,13 +631,9 @@ static struct synth_field *parse_synth_field(int argc, const char **argv, ...@@ -630,13 +631,9 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
field_type++; field_type++;
len = strlen(field_type) + 1; len = strlen(field_type) + 1;
if (array) { if (array)
int l = strlen(array); len += strlen(array);
if (l && array[l - 1] == ';')
l--;
len += l;
}
if (prefix) if (prefix)
len += strlen(prefix); len += strlen(prefix);
...@@ -645,14 +642,18 @@ static struct synth_field *parse_synth_field(int argc, const char **argv, ...@@ -645,14 +642,18 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
ret = -ENOMEM; ret = -ENOMEM;
goto free; goto free;
} }
seq_buf_init(&s, field->type, len);
if (prefix) if (prefix)
strcat(field->type, prefix); seq_buf_puts(&s, prefix);
strcat(field->type, field_type); seq_buf_puts(&s, field_type);
if (array) { if (array) {
strcat(field->type, array); seq_buf_puts(&s, array);
if (field->type[len - 1] == ';') if (s.buffer[s.len - 1] == ';')
field->type[len - 1] = '\0'; s.len--;
} }
if (WARN_ON_ONCE(!seq_buf_buffer_left(&s)))
goto free;
s.buffer[s.len] = '\0';
size = synth_field_size(field->type); size = synth_field_size(field->type);
if (size < 0) { if (size < 0) {
...@@ -663,14 +664,21 @@ static struct synth_field *parse_synth_field(int argc, const char **argv, ...@@ -663,14 +664,21 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
if (synth_field_is_string(field->type)) { if (synth_field_is_string(field->type)) {
char *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) { if (!type) {
ret = -ENOMEM; ret = -ENOMEM;
goto free; goto free;
} }
strcat(type, "__data_loc "); seq_buf_init(&s, type, len);
strcat(type, field->type); 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); kfree(field->type);
field->type = type; field->type = type;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment