diff options
Diffstat (limited to 'net/sctp/input.c')
-rw-r--r-- | net/sctp/input.c | 40 |
1 files changed, 21 insertions, 19 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c index 0e06a278d2a9..41eb2ec10460 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -473,15 +473,14 @@ struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb, struct sctp_association **app, struct sctp_transport **tpp) { + struct sctp_init_chunk *chunkhdr, _chunkhdr; union sctp_addr saddr; union sctp_addr daddr; struct sctp_af *af; struct sock *sk = NULL; struct sctp_association *asoc; struct sctp_transport *transport = NULL; - struct sctp_init_chunk *chunkhdr; __u32 vtag = ntohl(sctphdr->vtag); - int len = skb->len - ((void *)sctphdr - (void *)skb->data); *app = NULL; *tpp = NULL; @@ -516,13 +515,16 @@ struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb, * discard the packet. */ if (vtag == 0) { - chunkhdr = (void *)sctphdr + sizeof(struct sctphdr); - if (len < sizeof(struct sctphdr) + sizeof(sctp_chunkhdr_t) - + sizeof(__be32) || + /* chunk header + first 4 octects of init header */ + chunkhdr = skb_header_pointer(skb, skb_transport_offset(skb) + + sizeof(struct sctphdr), + sizeof(struct sctp_chunkhdr) + + sizeof(__be32), &_chunkhdr); + if (!chunkhdr || chunkhdr->chunk_hdr.type != SCTP_CID_INIT || - ntohl(chunkhdr->init_hdr.init_tag) != asoc->c.my_vtag) { + ntohl(chunkhdr->init_hdr.init_tag) != asoc->c.my_vtag) goto out; - } + } else if (vtag != asoc->c.peer_vtag) { goto out; } @@ -661,19 +663,19 @@ out_unlock: */ static int sctp_rcv_ootb(struct sk_buff *skb) { - sctp_chunkhdr_t *ch, _ch; + struct sctp_chunkhdr *ch, _ch; int ch_end, offset = 0; /* Scan through all the chunks in the packet. */ do { /* Make sure we have at least the header there */ - if (offset + sizeof(sctp_chunkhdr_t) > skb->len) + if (offset + sizeof(_ch) > skb->len) break; ch = skb_header_pointer(skb, offset, sizeof(*ch), &_ch); /* Break out if chunk length is less then minimal. */ - if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t)) + if (ntohs(ch->length) < sizeof(_ch)) break; ch_end = offset + SCTP_PAD4(ntohs(ch->length)); @@ -1049,7 +1051,7 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct net *net, union sctp_addr *paddr = &addr; struct sctphdr *sh = sctp_hdr(skb); union sctp_params params; - sctp_init_chunk_t *init; + struct sctp_init_chunk *init; struct sctp_af *af; /* @@ -1068,7 +1070,7 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct net *net, /* Find the start of the TLVs and the end of the chunk. This is * the region we search for address parameters. */ - init = (sctp_init_chunk_t *)skb->data; + init = (struct sctp_init_chunk *)skb->data; /* Walk the parameters looking for embedded addresses. */ sctp_walk_params(params, init, init_hdr.params) { @@ -1104,7 +1106,7 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct net *net, */ static struct sctp_association *__sctp_rcv_asconf_lookup( struct net *net, - sctp_chunkhdr_t *ch, + struct sctp_chunkhdr *ch, const union sctp_addr *laddr, __be16 peer_port, struct sctp_transport **transportp) @@ -1142,7 +1144,7 @@ static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net, struct sctp_transport **transportp) { struct sctp_association *asoc = NULL; - sctp_chunkhdr_t *ch; + struct sctp_chunkhdr *ch; int have_auth = 0; unsigned int chunk_num = 1; __u8 *ch_end; @@ -1150,10 +1152,10 @@ static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net, /* Walk through the chunks looking for AUTH or ASCONF chunks * to help us find the association. */ - ch = (sctp_chunkhdr_t *) skb->data; + ch = (struct sctp_chunkhdr *)skb->data; do { /* Break out if chunk length is less then minimal. */ - if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t)) + if (ntohs(ch->length) < sizeof(*ch)) break; ch_end = ((__u8 *)ch) + SCTP_PAD4(ntohs(ch->length)); @@ -1190,7 +1192,7 @@ static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net, if (asoc) break; - ch = (sctp_chunkhdr_t *) ch_end; + ch = (struct sctp_chunkhdr *)ch_end; chunk_num++; } while (ch_end < skb_tail_pointer(skb)); @@ -1208,7 +1210,7 @@ static struct sctp_association *__sctp_rcv_lookup_harder(struct net *net, const union sctp_addr *laddr, struct sctp_transport **transportp) { - sctp_chunkhdr_t *ch; + struct sctp_chunkhdr *ch; /* We do not allow GSO frames here as we need to linearize and * then cannot guarantee frame boundaries. This shouldn't be an @@ -1218,7 +1220,7 @@ static struct sctp_association *__sctp_rcv_lookup_harder(struct net *net, if ((skb_shinfo(skb)->gso_type & SKB_GSO_SCTP) == SKB_GSO_SCTP) return NULL; - ch = (sctp_chunkhdr_t *) skb->data; + ch = (struct sctp_chunkhdr *)skb->data; /* The code below will attempt to walk the chunk and extract * parameter information. Before we do that, we need to verify |