android_kernel_motorola_sm6375/kernel
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Steven Rostedt (VMware) a98c81ab17 tracing: Have all levels of checks prevent recursion
commit ed65df63a39a3f6ed04f7258de8b6789e5021c18 upstream.

While writing an email explaining the "bit = 0" logic for a discussion on
making ftrace_test_recursion_trylock() disable preemption, I discovered a
path that makes the "not do the logic if bit is zero" unsafe.

The recursion logic is done in hot paths like the function tracer. Thus,
any code executed causes noticeable overhead. Thus, tricks are done to try
to limit the amount of code executed. This included the recursion testing
logic.

Having recursion testing is important, as there are many paths that can
end up in an infinite recursion cycle when tracing every function in the
kernel. Thus protection is needed to prevent that from happening.

Because it is OK to recurse due to different running context levels (e.g.
an interrupt preempts a trace, and then a trace occurs in the interrupt
handler), a set of bits are used to know which context one is in (normal,
softirq, irq and NMI). If a recursion occurs in the same level, it is
prevented*.

Then there are infrastructure levels of recursion as well. When more than
one callback is attached to the same function to trace, it calls a loop
function to iterate over all the callbacks. Both the callbacks and the
loop function have recursion protection. The callbacks use the
"ftrace_test_recursion_trylock()" which has a "function" set of context
bits to test, and the loop function calls the internal
trace_test_and_set_recursion() directly, with an "internal" set of bits.

If an architecture does not implement all the features supported by ftrace
then the callbacks are never called directly, and the loop function is
called instead, which will implement the features of ftrace.

Since both the loop function and the callbacks do recursion protection, it
was seemed unnecessary to do it in both locations. Thus, a trick was made
to have the internal set of recursion bits at a more significant bit
location than the function bits. Then, if any of the higher bits were set,
the logic of the function bits could be skipped, as any new recursion
would first have to go through the loop function.

This is true for architectures that do not support all the ftrace
features, because all functions being traced must first go through the
loop function before going to the callbacks. But this is not true for
architectures that support all the ftrace features. That's because the
loop function could be called due to two callbacks attached to the same
function, but then a recursion function inside the callback could be
called that does not share any other callback, and it will be called
directly.

i.e.

 traced_function_1: [ more than one callback tracing it ]
   call loop_func

 loop_func:
   trace_recursion set internal bit
   call callback

 callback:
   trace_recursion [ skipped because internal bit is set, return 0 ]
   call traced_function_2

 traced_function_2: [ only traced by above callback ]
   call callback

 callback:
   trace_recursion [ skipped because internal bit is set, return 0 ]
   call traced_function_2

 [ wash, rinse, repeat, BOOM! out of shampoo! ]

Thus, the "bit == 0 skip" trick is not safe, unless the loop function is
call for all functions.

Since we want to encourage architectures to implement all ftrace features,
having them slow down due to this extra logic may encourage the
maintainers to update to the latest ftrace features. And because this
logic is only safe for them, remove it completely.

 [*] There is on layer of recursion that is allowed, and that is to allow
     for the transition between interrupt context (normal -> softirq ->
     irq -> NMI), because a trace may occur before the context update is
     visible to the trace recursion logic.

Link: https://lore.kernel.org/all/609b565a-ed6e-a1da-f025-166691b5d994@linux.alibaba.com/
Link: https://lkml.kernel.org/r/20211018154412.09fcad3c@gandalf.local.home

Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "James E.J. Bottomley" <James.Bottomley@hansenpartnership.com>
Cc: Helge Deller <deller@gmx.de>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Borislav Petkov <bp@alien8.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Jiri Kosina <jikos@kernel.org>
Cc: Miroslav Benes <mbenes@suse.cz>
Cc: Joe Lawrence <joe.lawrence@redhat.com>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Jisheng Zhang <jszhang@kernel.org>
Cc: =?utf-8?b?546L6LSH?= <yun.wang@linux.alibaba.com>
Cc: Guo Ren <guoren@kernel.org>
Cc: stable@vger.kernel.org
Fixes: edc15cafcb ("tracing: Avoid unnecessary multiple recursion checks")
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-10-27 09:54:29 +02:00
..
bpf bpf: Fix integer overflow in prealloc_elems_and_freelist() 2021-10-13 10:08:18 +02:00
cgroup cgroup/cpuset: Fix a partition bug with hotplug 2021-09-15 09:47:32 +02:00
configs
debug kdb: Make memory allocations more robust 2021-03-04 10:26:10 +01:00
dma dma-debug: fix sg checks in debug_dma_map_sg() 2021-10-27 09:54:25 +02:00
events events: Reuse value read using READ_ONCE instead of re-reading it 2021-09-22 12:26:41 +02:00
gcov gcov: re-fix clang-11+ support 2021-04-14 08:24:10 +02:00
irq genirq/timings: Fix error return code in irq_timings_test_irqs() 2021-09-15 09:47:29 +02:00
livepatch
locking locking/mutex: Fix HANDOFF condition 2021-09-15 09:47:25 +02:00
power PM: EM: Increase energy calculation precision 2021-09-15 09:47:33 +02:00
printk printk: fix deadlock when kernel panic 2021-03-04 10:26:50 +01:00
rcu rcu/tree: Handle VM stoppage in stall detection 2021-09-15 09:47:26 +02:00
sched cpufreq: schedutil: Use kobject release() method to free sugov_tunables 2021-10-06 15:42:29 +02:00
time Revert "posix-cpu-timers: Force next expiration recalc after itimer reset" 2021-09-16 12:56:13 +02:00
trace tracing: Have all levels of checks prevent recursion 2021-10-27 09:54:29 +02:00
.gitignore kbuild: update config_data.gz only when the content of .config is changed 2021-05-11 14:04:16 +02:00
acct.c
async.c
audit.c audit: fix a net reference leak in audit_list_rules_send() 2020-06-22 09:30:59 +02:00
audit.h audit: fix a net reference leak in audit_list_rules_send() 2020-06-22 09:30:59 +02:00
audit_fsnotify.c
audit_tree.c audit: move put_tree() to avoid trim_trees refcount underflow and UAF 2021-09-03 10:08:16 +02:00
audit_watch.c audit: CONFIG_CHANGE don't log internal bookkeeping as an event 2020-10-01 13:17:32 +02:00
auditfilter.c audit: fix a net reference leak in audit_list_rules_send() 2020-06-22 09:30:59 +02:00
auditsc.c audit: fix possible null-pointer dereference in audit_filter_rules 2021-10-27 09:54:27 +02:00
backtracetest.c
bounds.c
capability.c
compat.c
configs.c
context_tracking.c
cpu.c cpu/hotplug: Cure the cpusets trainwreck 2021-07-19 08:53:15 +02:00
cpu_pm.c kernel/cpu_pm: Fix uninitted local in cpu_pm 2020-06-22 09:31:22 +02:00
crash_core.c
crash_dump.c
cred.c
delayacct.c
dma.c
exec_domain.c
exit.c don't dump the threads that had been already exiting when zapped. 2020-11-18 19:20:31 +01:00
extable.c
fail_function.c fail_function: Remove a redundant mutex unlock 2020-11-24 13:29:18 +01:00
fork.c mm/hugetlb: initialize hugetlb_usage in mm_init 2021-09-22 12:26:37 +02:00
freezer.c
futex.c mm, futex: fix shared futex pgoff on shmem huge page 2021-06-30 08:47:55 -04:00
gen_kheaders.sh kbuild: add variables for compression tools 2020-09-03 11:27:10 +02:00
groups.c
hung_task.c
iomem.c
irq_work.c
jump_label.c
kallsyms.c kallsyms: Refactor kallsyms_show_value() to take cred 2020-07-16 08:16:44 +02:00
kcmp.c exec: Transform exec_update_mutex into a rw_semaphore 2021-01-09 13:44:55 +01:00
Kconfig.freezer
Kconfig.hz
Kconfig.locks
Kconfig.preempt
kcov.c
kexec.c
kexec_core.c kernel: kexec: remove the lock operation of system_transition_mutex 2021-02-03 23:25:56 +01:00
kexec_elf.c
kexec_file.c kernel: kexec_file: fix error return code of kexec_calculate_store_digests() 2021-05-19 10:08:28 +02:00
kexec_internal.h
kheaders.c
kmod.c kmod: make request_module() return an error when autoloading is disabled 2020-04-17 10:50:22 +02:00
kprobes.c tracing/kprobe: Fix to support kretprobe events on unloaded modules 2021-02-13 13:52:54 +01:00
ksysfs.c
kthread.c kthread: Fix PF_KTHREAD vs to_kthread() race 2021-09-12 08:56:39 +02:00
latencytop.c
Makefile kbuild: update config_data.gz only when the content of .config is changed 2021-05-11 14:04:16 +02:00
module-internal.h
module.c module: limit enabling module.sig_enforce 2021-06-30 08:47:42 -04:00
module_signature.c module: harden ELF info handling 2021-04-07 14:47:38 +02:00
module_signing.c module: harden ELF info handling 2021-04-07 14:47:38 +02:00
notifier.c kernel/notifier.c: intercept duplicate registrations to avoid infinite loops 2020-10-01 13:17:23 +02:00
nsproxy.c
padata.c padata: add separate cpuhp node for CPUHP_PADATA_DEAD 2020-06-17 16:40:22 +02:00
panic.c
params.c
pid.c
pid_namespace.c memcg: enable accounting for pids in nested pid namespaces 2021-09-22 12:26:37 +02:00
profile.c profiling: fix shift-out-of-bounds bugs 2021-09-26 14:07:09 +02:00
ptrace.c ptrace: make ptrace() fail if the tracee changed its pid unexpectedly 2021-05-26 12:05:15 +02:00
range.c
reboot.c reboot: fix overflow parsing reboot cpu number 2020-11-18 19:20:30 +01:00
relay.c kernel/relay.c: fix memleak on destroy relay channel 2020-08-26 10:40:51 +02:00
resource.c /dev/mem: Revoke mappings when a driver claims the region 2020-06-24 17:50:35 +02:00
rseq.c
seccomp.c seccomp: Add missing return in non-void function 2021-03-04 10:26:45 +01:00
signal.c ptrace: fix task_join_group_stop() for the case when current is traced 2020-11-10 12:37:24 +01:00
smp.c smp: Fix smp_call_function_single_async prototype 2021-05-14 09:44:33 +02:00
smpboot.c kthread: Extract KTHREAD_IS_PER_CPU 2021-02-07 15:35:49 +01:00
smpboot.h
softirq.c
stackleak.c
stacktrace.c
stop_machine.c
sys.c prctl: allow to setup brk for et_dyn executables 2021-09-26 14:07:08 +02:00
sys_ni.c
sysctl-test.c kernel/sysctl-test: Add null pointer test for sysctl.c:proc_dointvec() 2020-10-01 13:17:10 +02:00
sysctl.c sysctl.c: fix underflow value setting risk in vm_table 2021-03-17 17:03:45 +01:00
sysctl_binary.c
task_work.c
taskstats.c
test_kprobes.c
torture.c
tracepoint.c tracepoint: Add tracepoint_probe_register_may_exist() for BPF tracing 2021-07-14 16:53:08 +02:00
tsacct.c
ucount.c
uid16.c
uid16.h
umh.c usermodehelper: reset umask to default before executing user process 2020-10-14 10:32:58 +02:00
up.c smp: Fix smp_call_function_single_async prototype 2021-05-14 09:44:33 +02:00
user-return-notifier.c
user.c
user_namespace.c
utsname.c
utsname_sysctl.c
watchdog.c watchdog/softlockup: Enforce that timestamp is valid on boot 2020-02-24 08:36:52 +01:00
watchdog_hld.c
workqueue.c workqueue: Fix possible memory leaks in wq_numa_init() 2021-09-22 12:26:30 +02:00
workqueue_internal.h