android_kernel_samsung_univ.../kernel/trace
Steven Rostedt (Red Hat) f199023137 ring-buffer: Prevent overflow of size in ring_buffer_resize()
commit 59643d1535eb220668692a5359de22545af579f6 upstream.

If the size passed to ring_buffer_resize() is greater than MAX_LONG - BUF_PAGE_SIZE
then the DIV_ROUND_UP() will return zero.

Here's the details:

  # echo 18014398509481980 > /sys/kernel/debug/tracing/buffer_size_kb

tracing_entries_write() processes this and converts kb to bytes.

 18014398509481980 << 10 = 18446744073709547520

and this is passed to ring_buffer_resize() as unsigned long size.

 size = DIV_ROUND_UP(size, BUF_PAGE_SIZE);

Where DIV_ROUND_UP(a, b) is (a + b - 1)/b

BUF_PAGE_SIZE is 4080 and here

 18446744073709547520 + 4080 - 1 = 18446744073709551599

where 18446744073709551599 is still smaller than 2^64

 2^64 - 18446744073709551599 = 17

But now 18446744073709551599 / 4080 = 4521260802379792

and size = size * 4080 = 18446744073709551360

This is checked to make sure its still greater than 2 * 4080,
which it is.

Then we convert to the number of buffer pages needed.

 nr_page = DIV_ROUND_UP(size, BUF_PAGE_SIZE)

but this time size is 18446744073709551360 and

 2^64 - (18446744073709551360 + 4080 - 1) = -3823

Thus it overflows and the resulting number is less than 4080, which makes

  3823 / 4080 = 0

an nr_pages is set to this. As we already checked against the minimum that
nr_pages may be, this causes the logic to fail as well, and we crash the
kernel.

There's no reason to have the two DIV_ROUND_UP() (that's just result of
historical code changes), clean up the code and fix this bug.

Fixes: 83f40318da ("ring-buffer: Make removal of ring buffer pages atomic")
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-06-01 12:15:49 -07:00
..
blktrace.c Most of the changes are clean ups and small fixes. Some of them have 2015-11-06 13:30:20 -08:00
bpf_trace.c bpf: make tracing helpers gpl only 2015-10-26 21:53:34 -07:00
ftrace.c Most of the changes are clean ups and small fixes. Some of them have 2015-11-06 13:30:20 -08:00
Kconfig Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2015-11-10 18:11:41 -08:00
Makefile
power-traces.c
ring_buffer_benchmark.c ring_buffer: Remove unneeded smp_wmb() before wakeup of reader benchmark 2015-11-03 16:19:02 -05:00
ring_buffer.c ring-buffer: Prevent overflow of size in ring_buffer_resize() 2016-06-01 12:15:49 -07:00
rpm-traces.c
trace_benchmark.c tracing: Only benchmark the time tracepoints take if tracing is on 2015-11-02 13:34:58 -05:00
trace_benchmark.h
trace_branch.c tracing: Remove {start,stop}_branch_trace 2015-10-21 10:10:09 -04:00
trace_clock.c
trace_entries.h
trace_event_perf.c treewide: Remove old email address 2015-11-23 09:44:58 +01:00
trace_events_filter_test.h
trace_events_filter.c tracing: Do not have 'comm' filter override event 'comm' field 2016-03-09 15:34:52 -08:00
trace_events_trigger.c
trace_events.c tracing: Don't display trigger file for events that can't be enabled 2016-05-11 11:21:13 +02:00
trace_export.c tracing: ftrace_event_is_function() can return boolean 2015-11-02 14:28:05 -05:00
trace_functions_graph.c tracing: Remove unused ftrace_cpu_disabled per cpu variable 2015-11-07 13:25:14 -05:00
trace_functions.c
trace_irqsoff.c tracing: Have preempt(irqs)off trace preempt disabled functions 2016-04-12 09:08:59 -07:00
trace_kdb.c tracing: Move trace_flags from global to a trace_array field 2015-09-30 15:22:55 -04:00
trace_kprobe.c lib: introduce strncpy_from_unsafe() 2015-08-28 16:27:27 -07:00
trace_mmiotrace.c tracing: Pass trace_array into trace_buffer_unlock_commit() 2015-09-25 17:38:44 -04:00
trace_nop.c
trace_output.c tracing: Move trace_flags from global to a trace_array field 2015-09-30 15:22:55 -04:00
trace_output.h tracing: Turn seq_print_user_ip() into a static function 2015-09-28 10:16:12 -04:00
trace_printk.c tracing: Fix trace_printk() to print when not using bprintk() 2016-04-12 09:09:00 -07:00
trace_probe.c
trace_probe.h kernel/trace_probe: is_good_name can be boolean 2015-09-22 13:11:30 -04:00
trace_sched_switch.c sched/core: Fix trace_sched_switch() 2015-10-06 17:08:15 +02:00
trace_sched_wakeup.c Most of the changes are clean ups and small fixes. Some of them have 2015-11-06 13:30:20 -08:00
trace_selftest_dynamic.c
trace_selftest.c
trace_seq.c
trace_stack.c tracing/stacktrace: Show entire trace if passed in function not found 2016-02-17 12:30:57 -08:00
trace_stat.c
trace_stat.h
trace_syscalls.c tracing: Move trace_flags from global to a trace_array field 2015-09-30 15:22:55 -04:00
trace_uprobe.c tracing/uprobes: Do not print '0x (null)' when offset is 0 2015-08-26 10:43:01 -03:00
trace.c tracing: Fix crash from reading trace_pipe with sendfile 2016-04-12 09:08:59 -07:00
trace.h tracing: Remove unused ftrace_cpu_disabled per cpu variable 2015-11-07 13:25:14 -05:00