Skip to content

Commit 67029a4

Browse files
committed
Merge tag 'trace-v6.18-3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
Pull tracing fixes from Steven Rostedt: "The previous fix to trace_marker required updating trace_marker_raw as well. The difference between trace_marker_raw from trace_marker is that the raw version is for applications to write binary structures directly into the ring buffer instead of writing ASCII strings. This is for applications that will read the raw data from the ring buffer and get the data structures directly. It's a bit quicker than using the ASCII version. Unfortunately, it appears that our test suite has several tests that test writes to the trace_marker file, but lacks any tests to the trace_marker_raw file (this needs to be remedied). Two issues came about the update to the trace_marker_raw file that syzbot found: - Fix tracing_mark_raw_write() to use per CPU buffer The fix to use the per CPU buffer to copy from user space was needed for both the trace_maker and trace_maker_raw file. The fix for reading from user space into per CPU buffers properly fixed the trace_marker write function, but the trace_marker_raw file wasn't fixed properly. The user space data was correctly written into the per CPU buffer, but the code that wrote into the ring buffer still used the user space pointer and not the per CPU buffer that had the user space data already written. - Stop the fortify string warning from writing into trace_marker_raw After converting the copy_from_user_nofault() into a memcpy(), another issue appeared. As writes to the trace_marker_raw expects binary data, the first entry is a 4 byte identifier. The entry structure is defined as: struct { struct trace_entry ent; int id; char buf[]; }; The size of this structure is reserved on the ring buffer with: size = sizeof(*entry) + cnt; Then it is copied from the buffer into the ring buffer with: memcpy(&entry->id, buf, cnt); This use to be a copy_from_user_nofault(), but now converting it to a memcpy() triggers the fortify-string code, and causes a warning. The allocated space is actually more than what is copied, as the cnt used also includes the entry->id portion. Allocating sizeof(*entry) plus cnt is actually allocating 4 bytes more than what is needed. Change the size function to: size = struct_size(entry, buf, cnt - sizeof(entry->id)); And update the memcpy() to unsafe_memcpy()" * tag 'trace-v6.18-3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: tracing: Stop fortify-string from warning in tracing_mark_raw_write() tracing: Fix tracing_mark_raw_write() to use buf and not ubuf
2 parents c04022d + 54b91e5 commit 67029a4

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

kernel/trace/trace.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7441,7 +7441,8 @@ static ssize_t write_raw_marker_to_buffer(struct trace_array *tr,
74417441
ssize_t written;
74427442
size_t size;
74437443

7444-
size = sizeof(*entry) + cnt;
7444+
/* cnt includes both the entry->id and the data behind it. */
7445+
size = struct_size(entry, buf, cnt - sizeof(entry->id));
74457446

74467447
buffer = tr->array_buffer.buffer;
74477448

@@ -7455,7 +7456,10 @@ static ssize_t write_raw_marker_to_buffer(struct trace_array *tr,
74557456
return -EBADF;
74567457

74577458
entry = ring_buffer_event_data(event);
7458-
memcpy(&entry->id, buf, cnt);
7459+
unsafe_memcpy(&entry->id, buf, cnt,
7460+
"id and content already reserved on ring buffer"
7461+
"'buf' includes the 'id' and the data."
7462+
"'entry' was allocated with cnt from 'id'.");
74597463
written = cnt;
74607464

74617465
__buffer_unlock_commit(buffer, event);
@@ -7497,12 +7501,12 @@ tracing_mark_raw_write(struct file *filp, const char __user *ubuf,
74977501
if (tr == &global_trace) {
74987502
guard(rcu)();
74997503
list_for_each_entry_rcu(tr, &marker_copies, marker_list) {
7500-
written = write_raw_marker_to_buffer(tr, ubuf, cnt);
7504+
written = write_raw_marker_to_buffer(tr, buf, cnt);
75017505
if (written < 0)
75027506
break;
75037507
}
75047508
} else {
7505-
written = write_raw_marker_to_buffer(tr, ubuf, cnt);
7509+
written = write_raw_marker_to_buffer(tr, buf, cnt);
75067510
}
75077511

75087512
return written;

0 commit comments

Comments
 (0)