diff options
Diffstat (limited to 'net/sctp/input.c')
-rw-r--r-- | net/sctp/input.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c index b6493b3f11a9..2d7859c03fd2 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -472,15 +472,14 @@ struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb, | |||
472 | struct sctp_association **app, | 472 | struct sctp_association **app, |
473 | struct sctp_transport **tpp) | 473 | struct sctp_transport **tpp) |
474 | { | 474 | { |
475 | struct sctp_init_chunk *chunkhdr, _chunkhdr; | ||
475 | union sctp_addr saddr; | 476 | union sctp_addr saddr; |
476 | union sctp_addr daddr; | 477 | union sctp_addr daddr; |
477 | struct sctp_af *af; | 478 | struct sctp_af *af; |
478 | struct sock *sk = NULL; | 479 | struct sock *sk = NULL; |
479 | struct sctp_association *asoc; | 480 | struct sctp_association *asoc; |
480 | struct sctp_transport *transport = NULL; | 481 | struct sctp_transport *transport = NULL; |
481 | struct sctp_init_chunk *chunkhdr; | ||
482 | __u32 vtag = ntohl(sctphdr->vtag); | 482 | __u32 vtag = ntohl(sctphdr->vtag); |
483 | int len = skb->len - ((void *)sctphdr - (void *)skb->data); | ||
484 | 483 | ||
485 | *app = NULL; *tpp = NULL; | 484 | *app = NULL; *tpp = NULL; |
486 | 485 | ||
@@ -515,13 +514,16 @@ struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb, | |||
515 | * discard the packet. | 514 | * discard the packet. |
516 | */ | 515 | */ |
517 | if (vtag == 0) { | 516 | if (vtag == 0) { |
518 | chunkhdr = (void *)sctphdr + sizeof(struct sctphdr); | 517 | /* chunk header + first 4 octects of init header */ |
519 | if (len < sizeof(struct sctphdr) + sizeof(sctp_chunkhdr_t) | 518 | chunkhdr = skb_header_pointer(skb, skb_transport_offset(skb) + |
520 | + sizeof(__be32) || | 519 | sizeof(struct sctphdr), |
520 | sizeof(struct sctp_chunkhdr) + | ||
521 | sizeof(__be32), &_chunkhdr); | ||
522 | if (!chunkhdr || | ||
521 | chunkhdr->chunk_hdr.type != SCTP_CID_INIT || | 523 | chunkhdr->chunk_hdr.type != SCTP_CID_INIT || |
522 | ntohl(chunkhdr->init_hdr.init_tag) != asoc->c.my_vtag) { | 524 | ntohl(chunkhdr->init_hdr.init_tag) != asoc->c.my_vtag) |
523 | goto out; | 525 | goto out; |
524 | } | 526 | |
525 | } else if (vtag != asoc->c.peer_vtag) { | 527 | } else if (vtag != asoc->c.peer_vtag) { |
526 | goto out; | 528 | goto out; |
527 | } | 529 | } |