aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulian Anastasov <ja@ssi.bg>2013-03-09 16:25:06 -0500
committerSimon Horman <horms@verge.net.au>2013-03-18 20:37:27 -0400
commitcf2e39429c245245db889fffdfbdf3f889a6cb22 (patch)
tree34e0d72568893bafa61722e786716c3094b39288
parenta82783c91d5dce680dbd290ebf301a520b0e72a5 (diff)
ipvs: fix sctp chunk length order
Fix wrong but non-fatal access to chunk length. sch->length should be in network order, next chunk should be aligned to 4 bytes. Problem noticed in sparse output. Signed-off-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_sctp.c16
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 }