Skip to content

Commit afec62c

Browse files
edumazetkuba-moo
authored andcommitted
flow_dissector: use RCU protection to fetch dev_net()
__skb_flow_dissect() can be called from arbitrary contexts. It must extend its RCU protection section to include the call to dev_net(), which can become dev_net_rcu(). This makes sure the net structure can not disappear under us. Fixes: 9b52e3f ("flow_dissector: handle no-skb use case") Signed-off-by: Eric Dumazet <[email protected]> Reviewed-by: Kuniyuki Iwashima <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 4b8474a commit afec62c

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

net/core/flow_dissector.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,10 +1108,12 @@ bool __skb_flow_dissect(const struct net *net,
11081108
FLOW_DISSECTOR_KEY_BASIC,
11091109
target_container);
11101110

1111+
rcu_read_lock();
1112+
11111113
if (skb) {
11121114
if (!net) {
11131115
if (skb->dev)
1114-
net = dev_net(skb->dev);
1116+
net = dev_net_rcu(skb->dev);
11151117
else if (skb->sk)
11161118
net = sock_net(skb->sk);
11171119
}
@@ -1122,7 +1124,6 @@ bool __skb_flow_dissect(const struct net *net,
11221124
enum netns_bpf_attach_type type = NETNS_BPF_FLOW_DISSECTOR;
11231125
struct bpf_prog_array *run_array;
11241126

1125-
rcu_read_lock();
11261127
run_array = rcu_dereference(init_net.bpf.run_array[type]);
11271128
if (!run_array)
11281129
run_array = rcu_dereference(net->bpf.run_array[type]);
@@ -1150,17 +1151,17 @@ bool __skb_flow_dissect(const struct net *net,
11501151
prog = READ_ONCE(run_array->items[0].prog);
11511152
result = bpf_flow_dissect(prog, &ctx, n_proto, nhoff,
11521153
hlen, flags);
1153-
if (result == BPF_FLOW_DISSECTOR_CONTINUE)
1154-
goto dissect_continue;
1155-
__skb_flow_bpf_to_target(&flow_keys, flow_dissector,
1156-
target_container);
1157-
rcu_read_unlock();
1158-
return result == BPF_OK;
1154+
if (result != BPF_FLOW_DISSECTOR_CONTINUE) {
1155+
__skb_flow_bpf_to_target(&flow_keys, flow_dissector,
1156+
target_container);
1157+
rcu_read_unlock();
1158+
return result == BPF_OK;
1159+
}
11591160
}
1160-
dissect_continue:
1161-
rcu_read_unlock();
11621161
}
11631162

1163+
rcu_read_unlock();
1164+
11641165
if (dissector_uses_key(flow_dissector,
11651166
FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
11661167
struct ethhdr *eth = eth_hdr(skb);

0 commit comments

Comments
 (0)