Skip to content

Commit 23859ae

Browse files
committed
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
2 parents ed8780e + 761a8c5 commit 23859ae

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

kernel/trace/trace_events_synth.c

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
585585
struct synth_field *field;
586586
const char *prefix = NULL, *field_type = argv[0], *field_name, *array;
587587
int len, ret = 0;
588+
struct seq_buf s;
588589
ssize_t size;
589590

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

633-
if (array) {
634-
int l = strlen(array);
634+
if (array)
635+
len += strlen(array);
635636

636-
if (l && array[l - 1] == ';')
637-
l--;
638-
len += l;
639-
}
640637
if (prefix)
641638
len += strlen(prefix);
642639

@@ -645,14 +642,18 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
645642
ret = -ENOMEM;
646643
goto free;
647644
}
645+
seq_buf_init(&s, field->type, len);
648646
if (prefix)
649-
strcat(field->type, prefix);
650-
strcat(field->type, field_type);
647+
seq_buf_puts(&s, prefix);
648+
seq_buf_puts(&s, field_type);
651649
if (array) {
652-
strcat(field->type, array);
653-
if (field->type[len - 1] == ';')
654-
field->type[len - 1] = '\0';
650+
seq_buf_puts(&s, array);
651+
if (s.buffer[s.len - 1] == ';')
652+
s.len--;
655653
}
654+
if (WARN_ON_ONCE(!seq_buf_buffer_left(&s)))
655+
goto free;
656+
s.buffer[s.len] = '\0';
656657

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

666-
type = kzalloc(sizeof("__data_loc ") + strlen(field->type) + 1, GFP_KERNEL);
667+
len = sizeof("__data_loc ") + strlen(field->type) + 1;
668+
type = kzalloc(len, GFP_KERNEL);
667669
if (!type) {
668670
ret = -ENOMEM;
669671
goto free;
670672
}
671673

672-
strcat(type, "__data_loc ");
673-
strcat(type, field->type);
674+
seq_buf_init(&s, type, len);
675+
seq_buf_puts(&s, "__data_loc ");
676+
seq_buf_puts(&s, field->type);
677+
678+
if (WARN_ON_ONCE(!seq_buf_buffer_left(&s)))
679+
goto free;
680+
s.buffer[s.len] = '\0';
681+
674682
kfree(field->type);
675683
field->type = type;
676684

0 commit comments

Comments
 (0)