aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/nf_conntrack_proto.c
diff options
context:
space:
mode:
authorMartin Josefsson <gandalf@wlug.westbo.se>2006-11-28 20:35:08 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 00:31:10 -0500
commitae5718fb3dd0a11a4c9a061bf86417d52d58a6b3 (patch)
tree18d070424f6d2d74ee785c24d8f90744d61d3978 /net/netfilter/nf_conntrack_proto.c
parent605dcad6c85226e6d43387917b329d65b95cef39 (diff)
[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 <gandalf@wlug.westbo.se> Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/netfilter/nf_conntrack_proto.c')
-rw-r--r--net/netfilter/nf_conntrack_proto.c55
1 files changed, 49 insertions, 6 deletions
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 330b9acc62d..a6a3b1ddd00 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -28,7 +28,7 @@
28#include <net/netfilter/nf_conntrack_core.h> 28#include <net/netfilter/nf_conntrack_core.h>
29 29
30struct nf_conntrack_l4proto **nf_ct_protos[PF_MAX] __read_mostly; 30struct nf_conntrack_l4proto **nf_ct_protos[PF_MAX] __read_mostly;
31struct nf_conntrack_l3proto *nf_ct_l3protos[PF_MAX] __read_mostly; 31struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX] __read_mostly;
32 32
33struct nf_conntrack_l4proto * 33struct nf_conntrack_l4proto *
34__nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto) 34__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)
128{ 128{
129 int ret = 0; 129 int ret = 0;
130 130
131 if (proto->l3proto >= AF_MAX) {
132 ret = -EBUSY;
133 goto out;
134 }
135
131 write_lock_bh(&nf_conntrack_lock); 136 write_lock_bh(&nf_conntrack_lock);
132 if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) { 137 if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) {
133 ret = -EBUSY; 138 ret = -EBUSY;
134 goto out; 139 goto out_unlock;
135 } 140 }
136 nf_ct_l3protos[proto->l3proto] = proto; 141 nf_ct_l3protos[proto->l3proto] = proto;
137out:
138 write_unlock_bh(&nf_conntrack_lock);
139 142
143out_unlock:
144 write_unlock_bh(&nf_conntrack_lock);
145out:
140 return ret; 146 return ret;
141} 147}
142 148
143void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto) 149int nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
144{ 150{
151 int ret = 0;
152
153 if (proto->l3proto >= AF_MAX) {
154 ret = -EBUSY;
155 goto out;
156 }
157
145 write_lock_bh(&nf_conntrack_lock); 158 write_lock_bh(&nf_conntrack_lock);
159 if (nf_ct_l3protos[proto->l3proto] != proto) {
160 write_unlock_bh(&nf_conntrack_lock);
161 ret = -EBUSY;
162 goto out;
163 }
164
146 nf_ct_l3protos[proto->l3proto] = &nf_conntrack_l3proto_generic; 165 nf_ct_l3protos[proto->l3proto] = &nf_conntrack_l3proto_generic;
147 write_unlock_bh(&nf_conntrack_lock); 166 write_unlock_bh(&nf_conntrack_lock);
148 167
@@ -151,6 +170,9 @@ void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
151 170
152 /* Remove all contrack entries for this protocol */ 171 /* Remove all contrack entries for this protocol */
153 nf_ct_iterate_cleanup(kill_l3proto, proto); 172 nf_ct_iterate_cleanup(kill_l3proto, proto);
173
174out:
175 return ret;
154} 176}
155 177
156/* FIXME: Allow NULL functions and sub in pointers to generic for 178/* 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)
159{ 181{
160 int ret = 0; 182 int ret = 0;
161 183
184 if (l4proto->l3proto >= PF_MAX) {
185 ret = -EBUSY;
186 goto out;
187 }
188
162retry: 189retry:
163 write_lock_bh(&nf_conntrack_lock); 190 write_lock_bh(&nf_conntrack_lock);
164 if (nf_ct_protos[l4proto->l3proto]) { 191 if (nf_ct_protos[l4proto->l3proto]) {
@@ -210,9 +237,22 @@ out:
210 return ret; 237 return ret;
211} 238}
212 239
213void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto) 240int nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
214{ 241{
242 int ret = 0;
243
244 if (l4proto->l3proto >= PF_MAX) {
245 ret = -EBUSY;
246 goto out;
247 }
248
215 write_lock_bh(&nf_conntrack_lock); 249 write_lock_bh(&nf_conntrack_lock);
250 if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto]
251 != l4proto) {
252 write_unlock_bh(&nf_conntrack_lock);
253 ret = -EBUSY;
254 goto out;
255 }
216 nf_ct_protos[l4proto->l3proto][l4proto->l4proto] 256 nf_ct_protos[l4proto->l3proto][l4proto->l4proto]
217 = &nf_conntrack_l4proto_generic; 257 = &nf_conntrack_l4proto_generic;
218 write_unlock_bh(&nf_conntrack_lock); 258 write_unlock_bh(&nf_conntrack_lock);
@@ -222,4 +262,7 @@ void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
222 262
223 /* Remove all contrack entries for this protocol */ 263 /* Remove all contrack entries for this protocol */
224 nf_ct_iterate_cleanup(kill_l4proto, l4proto); 264 nf_ct_iterate_cleanup(kill_l4proto, l4proto);
265
266out:
267 return ret;
225} 268}