diff options
author | Steffen Klassert <steffen.klassert@secunet.com> | 2014-04-29 08:23:03 +0200 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2014-05-06 07:08:38 +0200 |
commit | edb666f07e539d92f63284213d72083ed8ac05ea (patch) | |
tree | 39db92cbd4f20dab09131f732937c8093d00bc48 /net/ipv6/xfrm6_protocol.c | |
parent | xfrm4: Properly handle unsupported protocols (diff) | |
download | linux-edb666f07e539d92f63284213d72083ed8ac05ea.tar.xz linux-edb666f07e539d92f63284213d72083ed8ac05ea.zip |
xfrm6: Properly handle unsupported protocols
We don't catch the case if an unsupported protocol is submitted
to the xfrm6 protocol handlers, this can lead to NULL pointer
dereferences. Fix this by adding the appropriate checks.
Fixes: 7e14ea15 ("xfrm6: Add IPsec protocol multiplexer")
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/ipv6/xfrm6_protocol.c')
-rw-r--r-- | net/ipv6/xfrm6_protocol.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c index 6ab989c486f7..54d13f8dbbae 100644 --- a/net/ipv6/xfrm6_protocol.c +++ b/net/ipv6/xfrm6_protocol.c @@ -50,6 +50,10 @@ int xfrm6_rcv_cb(struct sk_buff *skb, u8 protocol, int err) { int ret; struct xfrm6_protocol *handler; + struct xfrm6_protocol __rcu **head = proto_handlers(protocol); + + if (!head) + return 0; for_each_protocol_rcu(*proto_handlers(protocol), handler) if ((ret = handler->cb_handler(skb, err)) <= 0) @@ -184,10 +188,12 @@ int xfrm6_protocol_register(struct xfrm6_protocol *handler, struct xfrm6_protocol __rcu **pprev; struct xfrm6_protocol *t; bool add_netproto = false; - int ret = -EEXIST; int priority = handler->priority; + if (!proto_handlers(protocol) || !netproto(protocol)) + return -EINVAL; + mutex_lock(&xfrm6_protocol_mutex); if (!rcu_dereference_protected(*proto_handlers(protocol), @@ -230,6 +236,9 @@ int xfrm6_protocol_deregister(struct xfrm6_protocol *handler, struct xfrm6_protocol *t; int ret = -ENOENT; + if (!proto_handlers(protocol) || !netproto(protocol)) + return -EINVAL; + mutex_lock(&xfrm6_protocol_mutex); for (pprev = proto_handlers(protocol); |