Skip to content

Commit 59c9ab3

Browse files
committed
Merge tag 'trace-v6.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
Pull tracing fixes from Steven Rostedt: - Fix read out of bounds bug in tracing_splice_read_pipe() The size of the sub page being read can now be greater than a page. But the buffer used in tracing_splice_read_pipe() only allocates a page size. The data copied to the buffer is the amount in sub buffer which can overflow the buffer. Use min((size_t)trace_seq_used(&iter->seq), PAGE_SIZE) to limit the amount copied to the buffer to a max of PAGE_SIZE. - Fix the test for NULL from "!filter_hash" to "!*filter_hash" The add_next_hash() function checked for NULL at the wrong pointer level. - Do not use the array in trace_adjust_address() if there are no elements The trace_adjust_address() finds the offset of a module that was stored in the persistent buffer when reading the previous boot buffer to see if the address belongs to a module that was loaded in the previous boot. An array is created that matches currently loaded modules with previously loaded modules. The trace_adjust_address() uses that array to find the new offset of the address that's in the previous buffer. But if no module was loaded, it ends up reading the last element in an array that was never allocated. Check if nr_entries is zero and exit out early if it is. - Remove nested lock of trace_event_sem in print_event_fields() The print_event_fields() function iterates over the ftrace_events list and requires the trace_event_sem semaphore held for read. But this function is always called with that semaphore held for read. Remove the taking of the semaphore and replace it with lockdep_assert_held_read(&trace_event_sem) * tag 'trace-v6.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: tracing: Do not take trace_event_sem in print_event_fields() tracing: Fix trace_adjust_address() when there is no modules in scratch area ftrace: Fix NULL memory allocation check tracing: Fix oob write in trace_seq_to_buffer()
2 parents 593bde4 + 0a8f11f commit 59c9ab3

File tree

3 files changed

+9
-6
lines changed

3 files changed

+9
-6
lines changed

kernel/trace/ftrace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3436,7 +3436,7 @@ static int add_next_hash(struct ftrace_hash **filter_hash, struct ftrace_hash **
34363436

34373437
/* Copy the subops hash */
34383438
*filter_hash = alloc_and_copy_ftrace_hash(size_bits, subops_hash->filter_hash);
3439-
if (!filter_hash)
3439+
if (!*filter_hash)
34403440
return -ENOMEM;
34413441
/* Remove any notrace functions from the copy */
34423442
remove_hash(*filter_hash, subops_hash->notrace_hash);

kernel/trace/trace.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6043,8 +6043,10 @@ unsigned long trace_adjust_address(struct trace_array *tr, unsigned long addr)
60436043
tscratch = tr->scratch;
60446044
/* if there is no tscrach, module_delta must be NULL. */
60456045
module_delta = READ_ONCE(tr->module_delta);
6046-
if (!module_delta || tscratch->entries[0].mod_addr > addr)
6046+
if (!module_delta || !tscratch->nr_entries ||
6047+
tscratch->entries[0].mod_addr > addr) {
60476048
return addr + tr->text_delta;
6049+
}
60486050

60496051
/* Note that entries must be sorted. */
60506052
nr_entries = tscratch->nr_entries;
@@ -6821,13 +6823,14 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
68216823
/* Copy the data into the page, so we can start over. */
68226824
ret = trace_seq_to_buffer(&iter->seq,
68236825
page_address(spd.pages[i]),
6824-
trace_seq_used(&iter->seq));
6826+
min((size_t)trace_seq_used(&iter->seq),
6827+
PAGE_SIZE));
68256828
if (ret < 0) {
68266829
__free_page(spd.pages[i]);
68276830
break;
68286831
}
68296832
spd.partial[i].offset = 0;
6830-
spd.partial[i].len = trace_seq_used(&iter->seq);
6833+
spd.partial[i].len = ret;
68316834

68326835
trace_seq_init(&iter->seq);
68336836
}

kernel/trace/trace_output.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,11 +1042,12 @@ enum print_line_t print_event_fields(struct trace_iterator *iter,
10421042
struct trace_event_call *call;
10431043
struct list_head *head;
10441044

1045+
lockdep_assert_held_read(&trace_event_sem);
1046+
10451047
/* ftrace defined events have separate call structures */
10461048
if (event->type <= __TRACE_LAST_TYPE) {
10471049
bool found = false;
10481050

1049-
down_read(&trace_event_sem);
10501051
list_for_each_entry(call, &ftrace_events, list) {
10511052
if (call->event.type == event->type) {
10521053
found = true;
@@ -1056,7 +1057,6 @@ enum print_line_t print_event_fields(struct trace_iterator *iter,
10561057
if (call->event.type > __TRACE_LAST_TYPE)
10571058
break;
10581059
}
1059-
up_read(&trace_event_sem);
10601060
if (!found) {
10611061
trace_seq_printf(&iter->seq, "UNKNOWN TYPE %d\n", event->type);
10621062
goto out;

0 commit comments

Comments
 (0)