diff options
author | Liping Zhang <zlpnobody@gmail.com> | 2017-06-04 07:17:34 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2017-06-29 12:47:01 -0400 |
commit | deaa0a976b829af8a7886d8e2528a675cbe4dac8 (patch) | |
tree | 2542238b9e6a875891e42f682bd5c5350d3b6d30 | |
parent | e20bd60bf62a2448be873653c7febca1d4d73afc (diff) |
netfilter: nf_ct_dccp/sctp: fix memory leak after netns cleanup
After running the following commands for a while, kmemleak reported that
"1879 new suspected memory leaks" happened:
# while : ; do
ip netns add test
ip netns delete test
done
unreferenced object 0xffff88006342fa38 (size 1024):
comm "ip", pid 15477, jiffies 4295982857 (age 957.836s)
hex dump (first 32 bytes):
b8 b0 4d a0 ff ff ff ff c0 34 c3 59 00 88 ff ff ..M......4.Y....
04 00 00 00 a4 01 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff8190510a>] kmemleak_alloc+0x4a/0xa0
[<ffffffff81284130>] __kmalloc_track_caller+0x150/0x300
[<ffffffff812302d0>] kmemdup+0x20/0x50
[<ffffffffa04d598a>] dccp_init_net+0x8a/0x160 [nf_conntrack]
[<ffffffffa04cf9f5>] nf_ct_l4proto_pernet_register_one+0x25/0x90
...
unreferenced object 0xffff88006342da58 (size 1024):
comm "ip", pid 15477, jiffies 4295982857 (age 957.836s)
hex dump (first 32 bytes):
10 b3 4d a0 ff ff ff ff 04 35 c3 59 00 88 ff ff ..M......5.Y....
04 00 00 00 a4 01 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff8190510a>] kmemleak_alloc+0x4a/0xa0
[<ffffffff81284130>] __kmalloc_track_caller+0x150/0x300
[<ffffffff812302d0>] kmemdup+0x20/0x50
[<ffffffffa04d6a9d>] sctp_init_net+0x5d/0x130 [nf_conntrack]
[<ffffffffa04cf9f5>] nf_ct_l4proto_pernet_register_one+0x25/0x90
...
This is because we forgot to implement the get_net_proto for sctp and
dccp, so we won't invoke the nf_ct_unregister_sysctl to free the
ctl_table when do netns cleanup. Also note, we will fail to register
the sysctl for dccp/sctp either due to the lack of get_net_proto.
Fixes: c51d39010a1b ("netfilter: conntrack: built-in support for DCCP")
Fixes: a85406afeb3e ("netfilter: conntrack: built-in support for SCTP")
Cc: Davide Caratti <dcaratti@redhat.com>
Signed-off-by: Liping Zhang <zlpnobody@gmail.com>
Acked-by: Davide Caratti <dcaratti@redhat.com>
Acked-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | net/netfilter/nf_conntrack_proto_dccp.c | 7 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_proto_sctp.c | 7 |
2 files changed, 14 insertions, 0 deletions
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c index b553fdd68816..4707d997558a 100644 --- a/net/netfilter/nf_conntrack_proto_dccp.c +++ b/net/netfilter/nf_conntrack_proto_dccp.c | |||
@@ -872,6 +872,11 @@ static int dccp_init_net(struct net *net, u_int16_t proto) | |||
872 | return dccp_kmemdup_sysctl_table(net, pn, dn); | 872 | return dccp_kmemdup_sysctl_table(net, pn, dn); |
873 | } | 873 | } |
874 | 874 | ||
875 | static struct nf_proto_net *dccp_get_net_proto(struct net *net) | ||
876 | { | ||
877 | return &net->ct.nf_ct_proto.dccp.pn; | ||
878 | } | ||
879 | |||
875 | struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 __read_mostly = { | 880 | struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 __read_mostly = { |
876 | .l3proto = AF_INET, | 881 | .l3proto = AF_INET, |
877 | .l4proto = IPPROTO_DCCP, | 882 | .l4proto = IPPROTO_DCCP, |
@@ -904,6 +909,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 __read_mostly = { | |||
904 | }, | 909 | }, |
905 | #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ | 910 | #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ |
906 | .init_net = dccp_init_net, | 911 | .init_net = dccp_init_net, |
912 | .get_net_proto = dccp_get_net_proto, | ||
907 | }; | 913 | }; |
908 | EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp4); | 914 | EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp4); |
909 | 915 | ||
@@ -939,5 +945,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 __read_mostly = { | |||
939 | }, | 945 | }, |
940 | #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ | 946 | #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ |
941 | .init_net = dccp_init_net, | 947 | .init_net = dccp_init_net, |
948 | .get_net_proto = dccp_get_net_proto, | ||
942 | }; | 949 | }; |
943 | EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp6); | 950 | EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp6); |
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 1c5b14a6cab3..4ed976f137d3 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c | |||
@@ -786,6 +786,11 @@ static int sctp_init_net(struct net *net, u_int16_t proto) | |||
786 | return sctp_kmemdup_sysctl_table(pn, sn); | 786 | return sctp_kmemdup_sysctl_table(pn, sn); |
787 | } | 787 | } |
788 | 788 | ||
789 | static struct nf_proto_net *sctp_get_net_proto(struct net *net) | ||
790 | { | ||
791 | return &net->ct.nf_ct_proto.sctp.pn; | ||
792 | } | ||
793 | |||
789 | struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = { | 794 | struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = { |
790 | .l3proto = PF_INET, | 795 | .l3proto = PF_INET, |
791 | .l4proto = IPPROTO_SCTP, | 796 | .l4proto = IPPROTO_SCTP, |
@@ -819,6 +824,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = { | |||
819 | }, | 824 | }, |
820 | #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ | 825 | #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ |
821 | .init_net = sctp_init_net, | 826 | .init_net = sctp_init_net, |
827 | .get_net_proto = sctp_get_net_proto, | ||
822 | }; | 828 | }; |
823 | EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_sctp4); | 829 | EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_sctp4); |
824 | 830 | ||
@@ -855,5 +861,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = { | |||
855 | #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ | 861 | #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ |
856 | #endif | 862 | #endif |
857 | .init_net = sctp_init_net, | 863 | .init_net = sctp_init_net, |
864 | .get_net_proto = sctp_get_net_proto, | ||
858 | }; | 865 | }; |
859 | EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_sctp6); | 866 | EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_sctp6); |