Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit deaa0a97 authored by Liping Zhang's avatar Liping Zhang Committed by Pablo Neira Ayuso
Browse files

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: c51d3901 ("netfilter: conntrack: built-in support for DCCP")
Fixes: a85406af ("netfilter: conntrack: built-in support for SCTP")
Cc: Davide Caratti <dcaratti@redhat.com>
Signed-off-by: default avatarLiping Zhang <zlpnobody@gmail.com>
Acked-by: default avatarDavide Caratti <dcaratti@redhat.com>
Acked-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent e20bd60b
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -872,6 +872,11 @@ static int dccp_init_net(struct net *net, u_int16_t proto)
	return dccp_kmemdup_sysctl_table(net, pn, dn);
}

static struct nf_proto_net *dccp_get_net_proto(struct net *net)
{
	return &net->ct.nf_ct_proto.dccp.pn;
}

struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 __read_mostly = {
	.l3proto		= AF_INET,
	.l4proto		= IPPROTO_DCCP,
@@ -904,6 +909,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 __read_mostly = {
	},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
	.init_net		= dccp_init_net,
	.get_net_proto		= dccp_get_net_proto,
};
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp4);

@@ -939,5 +945,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 __read_mostly = {
	},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
	.init_net		= dccp_init_net,
	.get_net_proto		= dccp_get_net_proto,
};
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp6);
+7 −0
Original line number Diff line number Diff line
@@ -786,6 +786,11 @@ static int sctp_init_net(struct net *net, u_int16_t proto)
	return sctp_kmemdup_sysctl_table(pn, sn);
}

static struct nf_proto_net *sctp_get_net_proto(struct net *net)
{
	return &net->ct.nf_ct_proto.sctp.pn;
}

struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
	.l3proto		= PF_INET,
	.l4proto 		= IPPROTO_SCTP,
@@ -819,6 +824,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
	},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
	.init_net		= sctp_init_net,
	.get_net_proto		= sctp_get_net_proto,
};
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_sctp4);

@@ -855,5 +861,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
#endif
	.init_net		= sctp_init_net,
	.get_net_proto		= sctp_get_net_proto,
};
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_sctp6);