From ae5718fb3dd0a11a4c9a061bf86417d52d58a6b3 Mon Sep 17 00:00:00 2001 From: Martin Josefsson Date: Wed, 29 Nov 2006 02:35:08 +0100 Subject: [NETFILTER]: nf_conntrack: more sanity checks in protocol registration/unregistration Add some more sanity checks when registering/unregistering l3/l4 protocols. Signed-off-by: Martin Josefsson Signed-off-by: Patrick McHardy --- net/netfilter/nf_conntrack_proto.c | 55 +++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 6 deletions(-) (limited to 'net/netfilter/nf_conntrack_proto.c') diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 330b9acc62d8..a6a3b1ddd00d 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -28,7 +28,7 @@ #include struct nf_conntrack_l4proto **nf_ct_protos[PF_MAX] __read_mostly; -struct nf_conntrack_l3proto *nf_ct_l3protos[PF_MAX] __read_mostly; +struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX] __read_mostly; struct nf_conntrack_l4proto * __nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto) @@ -128,21 +128,40 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto) { int ret = 0; + if (proto->l3proto >= AF_MAX) { + ret = -EBUSY; + goto out; + } + write_lock_bh(&nf_conntrack_lock); if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) { ret = -EBUSY; - goto out; + goto out_unlock; } nf_ct_l3protos[proto->l3proto] = proto; -out: - write_unlock_bh(&nf_conntrack_lock); +out_unlock: + write_unlock_bh(&nf_conntrack_lock); +out: return ret; } -void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto) +int nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto) { + int ret = 0; + + if (proto->l3proto >= AF_MAX) { + ret = -EBUSY; + goto out; + } + write_lock_bh(&nf_conntrack_lock); + if (nf_ct_l3protos[proto->l3proto] != proto) { + write_unlock_bh(&nf_conntrack_lock); + ret = -EBUSY; + goto out; + } + nf_ct_l3protos[proto->l3proto] = &nf_conntrack_l3proto_generic; write_unlock_bh(&nf_conntrack_lock); @@ -151,6 +170,9 @@ void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto) /* Remove all contrack entries for this protocol */ nf_ct_iterate_cleanup(kill_l3proto, proto); + +out: + return ret; } /* FIXME: Allow NULL functions and sub in pointers to generic for @@ -159,6 +181,11 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto) { int ret = 0; + if (l4proto->l3proto >= PF_MAX) { + ret = -EBUSY; + goto out; + } + retry: write_lock_bh(&nf_conntrack_lock); if (nf_ct_protos[l4proto->l3proto]) { @@ -210,9 +237,22 @@ out: return ret; } -void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto) +int nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto) { + int ret = 0; + + if (l4proto->l3proto >= PF_MAX) { + ret = -EBUSY; + goto out; + } + write_lock_bh(&nf_conntrack_lock); + if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] + != l4proto) { + write_unlock_bh(&nf_conntrack_lock); + ret = -EBUSY; + goto out; + } nf_ct_protos[l4proto->l3proto][l4proto->l4proto] = &nf_conntrack_l4proto_generic; write_unlock_bh(&nf_conntrack_lock); @@ -222,4 +262,7 @@ void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto) /* Remove all contrack entries for this protocol */ nf_ct_iterate_cleanup(kill_l4proto, l4proto); + +out: + return ret; } -- cgit v1.2.3