Skip to content

Commit 63a8dfb

Browse files
committed
function_graph: Add READ_ONCE() when accessing fgraph_array[]
In function_graph_enter() there's a loop that looks at fgraph_array[] elements which are fgraph_ops. It first tests if it is a fgraph_stub op, and if so skips it, as that's just there as a place holder. Then it checks the fgraph_ops filters to see if the ops wants to trace the current function. But if the compiler reloads the fgraph_array[] after the check against fgraph_stub, it could race with the fgraph_array[] being updated with the fgraph_stub. That would cause the stub to be processed. But the stub has a null "func_hash" field which will cause a NULL pointer dereference. Add a READ_ONCE() so that the gops that is compared against the fgraph_stub is also the gops that is processed later. Link: https://lore.kernel.org/all/CA+G9fYsSVJQZH=nM=1cjTc94PgSnMF9y65BnOv6XSoCG_b6wmw@mail.gmail.com/ Link: https://lore.kernel.org/linux-trace-kernel/[email protected] Cc: Mark Rutland <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Fixes: cc60ee8 ("function_graph: Use static_call and branch to optimize entry function") Reported-by: Naresh Kamboju <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]> Acked-by: Masami Hiramatsu (Google) <[email protected]>
1 parent 9b5a45e commit 63a8dfb

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

kernel/trace/fgraph.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ int function_graph_enter(unsigned long ret, unsigned long func,
641641
{
642642
for_each_set_bit(i, &fgraph_array_bitmask,
643643
sizeof(fgraph_array_bitmask) * BITS_PER_BYTE) {
644-
struct fgraph_ops *gops = fgraph_array[i];
644+
struct fgraph_ops *gops = READ_ONCE(fgraph_array[i]);
645645
int save_curr_ret_stack;
646646

647647
if (gops == &fgraph_stub)

0 commit comments

Comments
 (0)