summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorSridhar Samudrala <sri@us.ibm.com>2005-07-18 22:44:10 +0200
committerDavid S. Miller <davem@davemloft.net>2005-07-18 22:44:10 +0200
commitd1ad1ff299dd908d07c5e5f27f88bbdb235eb7a5 (patch)
tree03f66679f4a153ec06fde913907f392503f4b5e5 /net
parent[SCTP]: Audit return code of create_proc_* (diff)
downloadlinux-d1ad1ff299dd908d07c5e5f27f88bbdb235eb7a5.tar.xz
linux-d1ad1ff299dd908d07c5e5f27f88bbdb235eb7a5.zip
[SCTP]: Fix potential null pointer dereference while handling an icmp error
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/sctp/input.c45
-rw-r--r--net/sctp/ipv6.c7
2 files changed, 15 insertions, 37 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 5e085e041a6e..742be9171b7d 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -351,7 +351,6 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
*
*/
void sctp_icmp_proto_unreachable(struct sock *sk,
- struct sctp_endpoint *ep,
struct sctp_association *asoc,
struct sctp_transport *t)
{
@@ -367,7 +366,6 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
/* Common lookup code for icmp/icmpv6 error handler. */
struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
struct sctphdr *sctphdr,
- struct sctp_endpoint **epp,
struct sctp_association **app,
struct sctp_transport **tpp)
{
@@ -375,11 +373,10 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
union sctp_addr daddr;
struct sctp_af *af;
struct sock *sk = NULL;
- struct sctp_endpoint *ep = NULL;
struct sctp_association *asoc = NULL;
struct sctp_transport *transport = NULL;
- *app = NULL; *epp = NULL; *tpp = NULL;
+ *app = NULL; *tpp = NULL;
af = sctp_get_af_specific(family);
if (unlikely(!af)) {
@@ -394,26 +391,15 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
* packet.
*/
asoc = __sctp_lookup_association(&saddr, &daddr, &transport);
- if (!asoc) {
- /* If there is no matching association, see if it matches any
- * endpoint. This may happen for an ICMP error generated in
- * response to an INIT_ACK.
- */
- ep = __sctp_rcv_lookup_endpoint(&daddr);
- if (!ep) {
- return NULL;
- }
- }
+ if (!asoc)
+ return NULL;
- if (asoc) {
- sk = asoc->base.sk;
+ sk = asoc->base.sk;
- if (ntohl(sctphdr->vtag) != asoc->c.peer_vtag) {
- ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
- goto out;
- }
- } else
- sk = ep->base.sk;
+ if (ntohl(sctphdr->vtag) != asoc->c.peer_vtag) {
+ ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
+ goto out;
+ }
sctp_bh_lock_sock(sk);
@@ -423,7 +409,6 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
if (sock_owned_by_user(sk))
NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS);
- *epp = ep;
*app = asoc;
*tpp = transport;
return sk;
@@ -432,21 +417,16 @@ out:
sock_put(sk);
if (asoc)
sctp_association_put(asoc);
- if (ep)
- sctp_endpoint_put(ep);
return NULL;
}
/* Common cleanup code for icmp/icmpv6 error handler. */
-void sctp_err_finish(struct sock *sk, struct sctp_endpoint *ep,
- struct sctp_association *asoc)
+void sctp_err_finish(struct sock *sk, struct sctp_association *asoc)
{
sctp_bh_unlock_sock(sk);
sock_put(sk);
if (asoc)
sctp_association_put(asoc);
- if (ep)
- sctp_endpoint_put(ep);
}
/*
@@ -471,7 +451,6 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
int type = skb->h.icmph->type;
int code = skb->h.icmph->code;
struct sock *sk;
- struct sctp_endpoint *ep;
struct sctp_association *asoc;
struct sctp_transport *transport;
struct inet_sock *inet;
@@ -488,7 +467,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
savesctp = skb->h.raw;
skb->nh.iph = iph;
skb->h.raw = (char *)sh;
- sk = sctp_err_lookup(AF_INET, skb, sh, &ep, &asoc, &transport);
+ sk = sctp_err_lookup(AF_INET, skb, sh, &asoc, &transport);
/* Put back, the original pointers. */
skb->nh.raw = saveip;
skb->h.raw = savesctp;
@@ -515,7 +494,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
}
else {
if (ICMP_PROT_UNREACH == code) {
- sctp_icmp_proto_unreachable(sk, ep, asoc,
+ sctp_icmp_proto_unreachable(sk, asoc,
transport);
goto out_unlock;
}
@@ -544,7 +523,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
}
out_unlock:
- sctp_err_finish(sk, ep, asoc);
+ sctp_err_finish(sk, asoc);
}
/*
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index c7e42d125b9c..e9b2fd480d61 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -91,7 +91,6 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
struct ipv6hdr *iph = (struct ipv6hdr *)skb->data;
struct sctphdr *sh = (struct sctphdr *)(skb->data + offset);
struct sock *sk;
- struct sctp_endpoint *ep;
struct sctp_association *asoc;
struct sctp_transport *transport;
struct ipv6_pinfo *np;
@@ -105,7 +104,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
savesctp = skb->h.raw;
skb->nh.ipv6h = iph;
skb->h.raw = (char *)sh;
- sk = sctp_err_lookup(AF_INET6, skb, sh, &ep, &asoc, &transport);
+ sk = sctp_err_lookup(AF_INET6, skb, sh, &asoc, &transport);
/* Put back, the original pointers. */
skb->nh.raw = saveip;
skb->h.raw = savesctp;
@@ -124,7 +123,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
goto out_unlock;
case ICMPV6_PARAMPROB:
if (ICMPV6_UNK_NEXTHDR == code) {
- sctp_icmp_proto_unreachable(sk, ep, asoc, transport);
+ sctp_icmp_proto_unreachable(sk, asoc, transport);
goto out_unlock;
}
break;
@@ -142,7 +141,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
}
out_unlock:
- sctp_err_finish(sk, ep, asoc);
+ sctp_err_finish(sk, asoc);
out:
if (likely(idev != NULL))
in6_dev_put(idev);