On Wed, May 20, 2020 at 10:24 AM Jakub Sitnicki <jakub@xxxxxxxxxxxxxx> wrote: > > When attaching a flow dissector program to a network namespace with > bpf(BPF_PROG_ATTACH, ...) we grab a reference to bpf_prog. > > If netns gets destroyed while a flow dissector is still attached, and there > are no other references to the prog, we leak the reference and the program > remains loaded. > > Leak can be reproduced by running flow dissector tests from selftests/bpf: > > # bpftool prog list > # ./test_flow_dissector.sh > ... > selftests: test_flow_dissector [PASS] > # bpftool prog list > 4: flow_dissector name _dissect tag e314084d332a5338 gpl > loaded_at 2020-05-20T18:50:53+0200 uid 0 > xlated 552B jited 355B memlock 4096B map_ids 3,4 > btf_id 4 > # > > Fix it by detaching the flow dissector program when netns is going away. > > Fixes: d58e468b1112 ("flow_dissector: implements flow dissector BPF hook") > Signed-off-by: Jakub Sitnicki <jakub@xxxxxxxxxxxxxx> > --- > > Discovered while working on bpf_link support for netns-attached progs. > Looks like bpf tree material so pushing it out separately. > > -jkbs > [...] > /** > * __skb_flow_get_ports - extract the upper layer ports and return them > * @skb: sk_buff to extract the ports from > @@ -1827,6 +1848,8 @@ EXPORT_SYMBOL(flow_keys_basic_dissector); > > static int __init init_default_flow_dissectors(void) > { > + int err; > + > skb_flow_dissector_init(&flow_keys_dissector, > flow_keys_dissector_keys, > ARRAY_SIZE(flow_keys_dissector_keys)); > @@ -1836,7 +1859,11 @@ static int __init init_default_flow_dissectors(void) > skb_flow_dissector_init(&flow_keys_basic_dissector, > flow_keys_basic_dissector_keys, > ARRAY_SIZE(flow_keys_basic_dissector_keys)); > - return 0; > + > + err = register_pernet_subsys(&flow_dissector_pernet_ops); > + > + WARN_ON(err); syzbot simulates memory allocation failures, which can bubble up here, so this WARN_ON will probably trigger. I wonder if this could be rewritten so that init fails, when registration fails? What are the consequences? > + return err; > } > > core_initcall(init_default_flow_dissectors); > -- > 2.25.4 >