Skip to content

Commit c8b186a

Browse files
aikrostedt
authored andcommitted
tracepoint: Fix race between tracing and removing tracepoint
When executing a tracepoint, the tracepoint's func is dereferenced twice - in __DO_TRACE() (where the returned pointer is checked) and later on in __traceiter_##_name where the returned pointer is dereferenced without checking which leads to races against tracepoint_removal_sync() and crashes. This adds a check before referencing the pointer in tracepoint_ptr_deref. Link: https://lkml.kernel.org/r/[email protected] Cc: [email protected] Fixes: d25e37d ("tracepoint: Optimize using static_call()") Acked-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Alexey Kardashevskiy <[email protected]> Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent 0188b87 commit c8b186a

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

include/linux/tracepoint.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -307,11 +307,13 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
307307
\
308308
it_func_ptr = \
309309
rcu_dereference_raw((&__tracepoint_##_name)->funcs); \
310-
do { \
311-
it_func = (it_func_ptr)->func; \
312-
__data = (it_func_ptr)->data; \
313-
((void(*)(void *, proto))(it_func))(__data, args); \
314-
} while ((++it_func_ptr)->func); \
310+
if (it_func_ptr) { \
311+
do { \
312+
it_func = (it_func_ptr)->func; \
313+
__data = (it_func_ptr)->data; \
314+
((void(*)(void *, proto))(it_func))(__data, args); \
315+
} while ((++it_func_ptr)->func); \
316+
} \
315317
return 0; \
316318
} \
317319
DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name);

0 commit comments

Comments
 (0)