Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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()

+9 -6
+1 -1
kernel/trace/ftrace.c
··· 3436 3436 3437 3437 /* Copy the subops hash */ 3438 3438 *filter_hash = alloc_and_copy_ftrace_hash(size_bits, subops_hash->filter_hash); 3439 - if (!filter_hash) 3439 + if (!*filter_hash) 3440 3440 return -ENOMEM; 3441 3441 /* Remove any notrace functions from the copy */ 3442 3442 remove_hash(*filter_hash, subops_hash->notrace_hash);
+6 -3
kernel/trace/trace.c
··· 6043 6043 tscratch = tr->scratch; 6044 6044 /* if there is no tscrach, module_delta must be NULL. */ 6045 6045 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) { 6047 6048 return addr + tr->text_delta; 6049 + } 6048 6050 6049 6051 /* Note that entries must be sorted. */ 6050 6052 nr_entries = tscratch->nr_entries; ··· 6823 6821 /* Copy the data into the page, so we can start over. */ 6824 6822 ret = trace_seq_to_buffer(&iter->seq, 6825 6823 page_address(spd.pages[i]), 6826 - trace_seq_used(&iter->seq)); 6824 + min((size_t)trace_seq_used(&iter->seq), 6825 + PAGE_SIZE)); 6827 6826 if (ret < 0) { 6828 6827 __free_page(spd.pages[i]); 6829 6828 break; 6830 6829 } 6831 6830 spd.partial[i].offset = 0; 6832 - spd.partial[i].len = trace_seq_used(&iter->seq); 6831 + spd.partial[i].len = ret; 6833 6832 6834 6833 trace_seq_init(&iter->seq); 6835 6834 }
+2 -2
kernel/trace/trace_output.c
··· 1042 1042 struct trace_event_call *call; 1043 1043 struct list_head *head; 1044 1044 1045 + lockdep_assert_held_read(&trace_event_sem); 1046 + 1045 1047 /* ftrace defined events have separate call structures */ 1046 1048 if (event->type <= __TRACE_LAST_TYPE) { 1047 1049 bool found = false; 1048 1050 1049 - down_read(&trace_event_sem); 1050 1051 list_for_each_entry(call, &ftrace_events, list) { 1051 1052 if (call->event.type == event->type) { 1052 1053 found = true; ··· 1057 1056 if (call->event.type > __TRACE_LAST_TYPE) 1058 1057 break; 1059 1058 } 1060 - up_read(&trace_event_sem); 1061 1059 if (!found) { 1062 1060 trace_seq_printf(&iter->seq, "UNKNOWN TYPE %d\n", event->type); 1063 1061 goto out;