Patch "tracing, synthetic events: Replace buggy strcat() with seq_buf operations" has been added to the 5.9-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    tracing, synthetic events: Replace buggy strcat() with seq_buf operations

to the 5.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     tracing-synthetic-events-replace-buggy-strcat-with-s.patch
and it can be found in the queue-5.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 1e5dd94addbfef346ce10ee9a919376b11b58ada
Author: Sasha Levin <sashal@xxxxxxxxxx>
Date:   Sun Nov 1 12:35:33 2020 -0500

    tracing, synthetic events: Replace buggy strcat() with seq_buf operations
    
    [ Upstream commit 761a8c58db6bc884994b28cd6d9707b467d680c1 ]
    
    There was a memory corruption bug happening while running the synthetic
    event selftests:
    
     kmemleak: Cannot insert 0xffff8c196fa2afe5 into the object search tree (overlaps existing)
     CPU: 5 PID: 6866 Comm: ftracetest Tainted: G        W         5.9.0-rc5-test+ #577
     Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v03.03 07/14/2016
     Call Trace:
      dump_stack+0x8d/0xc0
      create_object.cold+0x3b/0x60
      slab_post_alloc_hook+0x57/0x510
      ? tracing_map_init+0x178/0x340
      __kmalloc+0x1b1/0x390
      tracing_map_init+0x178/0x340
      event_hist_trigger_func+0x523/0xa40
      trigger_process_regex+0xc5/0x110
      event_trigger_write+0x71/0xd0
      vfs_write+0xca/0x210
      ksys_write+0x70/0xf0
      do_syscall_64+0x33/0x40
      entry_SYSCALL_64_after_hwframe+0x44/0xa9
     RIP: 0033:0x7fef0a63a487
     Code: 64 89 02 48 c7 c0 ff ff ff ff eb bb 0f 1f 80 00 00 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 48 89 54 24 18 48 89 74 24
     RSP: 002b:00007fff76f18398 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
     RAX: ffffffffffffffda RBX: 0000000000000039 RCX: 00007fef0a63a487
     RDX: 0000000000000039 RSI: 000055eb3b26d690 RDI: 0000000000000001
     RBP: 000055eb3b26d690 R08: 000000000000000a R09: 0000000000000038
     R10: 000055eb3b2cdb80 R11: 0000000000000246 R12: 0000000000000039
     R13: 00007fef0a70b500 R14: 0000000000000039 R15: 00007fef0a70b700
     kmemleak: Kernel memory leak detector disabled
     kmemleak: Object 0xffff8c196fa2afe0 (size 8):
     kmemleak:   comm "ftracetest", pid 6866, jiffies 4295082531
     kmemleak:   min_count = 1
     kmemleak:   count = 0
     kmemleak:   flags = 0x1
     kmemleak:   checksum = 0
     kmemleak:   backtrace:
          __kmalloc+0x1b1/0x390
          tracing_map_init+0x1be/0x340
          event_hist_trigger_func+0x523/0xa40
          trigger_process_regex+0xc5/0x110
          event_trigger_write+0x71/0xd0
          vfs_write+0xca/0x210
          ksys_write+0x70/0xf0
          do_syscall_64+0x33/0x40
          entry_SYSCALL_64_after_hwframe+0x44/0xa9
    
    The cause came down to a use of strcat() that was adding an string that was
    shorten, but the strcat() did not take that into account.
    
    strcat() is extremely dangerous as it does not care how big the buffer is.
    Replace it with seq_buf operations that prevent the buffer from being
    overwritten if what is being written is bigger than the buffer.
    
    Fixes: 10819e25799a ("tracing: Handle synthetic event array field type checking correctly")
    Reviewed-by: Tom Zanussi <zanussi@xxxxxxxxxx>
    Tested-by: Tom Zanussi <zanussi@xxxxxxxxxx>
    Signed-off-by: Steven Rostedt (VMware) <rostedt@xxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
index c8892156db341..65e8c27141c02 100644
--- a/kernel/trace/trace_events_synth.c
+++ b/kernel/trace/trace_events_synth.c
@@ -465,6 +465,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] == ';')
@@ -503,13 +504,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);
 
@@ -518,14 +515,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) {



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux