diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/ipvs/ip_vs_proto_sctp.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c index ae8ec6f27688..cd1d7298f7ba 100644 --- a/net/netfilter/ipvs/ip_vs_proto_sctp.c +++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c | |||
@@ -906,7 +906,7 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp, | |||
906 | sctp_chunkhdr_t _sctpch, *sch; | 906 | sctp_chunkhdr_t _sctpch, *sch; |
907 | unsigned char chunk_type; | 907 | unsigned char chunk_type; |
908 | int event, next_state; | 908 | int event, next_state; |
909 | int ihl; | 909 | int ihl, cofs; |
910 | 910 | ||
911 | #ifdef CONFIG_IP_VS_IPV6 | 911 | #ifdef CONFIG_IP_VS_IPV6 |
912 | ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr); | 912 | ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr); |
@@ -914,8 +914,8 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp, | |||
914 | ihl = ip_hdrlen(skb); | 914 | ihl = ip_hdrlen(skb); |
915 | #endif | 915 | #endif |
916 | 916 | ||
917 | sch = skb_header_pointer(skb, ihl + sizeof(sctp_sctphdr_t), | 917 | cofs = ihl + sizeof(sctp_sctphdr_t); |
918 | sizeof(_sctpch), &_sctpch); | 918 | sch = skb_header_pointer(skb, cofs, sizeof(_sctpch), &_sctpch); |
919 | if (sch == NULL) | 919 | if (sch == NULL) |
920 | return; | 920 | return; |
921 | 921 | ||
@@ -933,10 +933,12 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp, | |||
933 | */ | 933 | */ |
934 | if ((sch->type == SCTP_CID_COOKIE_ECHO) || | 934 | if ((sch->type == SCTP_CID_COOKIE_ECHO) || |
935 | (sch->type == SCTP_CID_COOKIE_ACK)) { | 935 | (sch->type == SCTP_CID_COOKIE_ACK)) { |
936 | sch = skb_header_pointer(skb, (ihl + sizeof(sctp_sctphdr_t) + | 936 | int clen = ntohs(sch->length); |
937 | sch->length), sizeof(_sctpch), &_sctpch); | 937 | |
938 | if (sch) { | 938 | if (clen >= sizeof(sctp_chunkhdr_t)) { |
939 | if (sch->type == SCTP_CID_ABORT) | 939 | sch = skb_header_pointer(skb, cofs + ALIGN(clen, 4), |
940 | sizeof(_sctpch), &_sctpch); | ||
941 | if (sch && sch->type == SCTP_CID_ABORT) | ||
940 | chunk_type = sch->type; | 942 | chunk_type = sch->type; |
941 | } | 943 | } |
942 | } | 944 | } |