diff options
Diffstat (limited to 'net/dccp/options.c')
-rw-r--r-- | net/dccp/options.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/net/dccp/options.c b/net/dccp/options.c index d361b5533309..d286cffe2c49 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/dccp.h> | 14 | #include <linux/dccp.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <asm/unaligned.h> | ||
17 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
18 | #include <linux/skbuff.h> | 19 | #include <linux/skbuff.h> |
19 | 20 | ||
@@ -59,6 +60,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
59 | unsigned char opt, len; | 60 | unsigned char opt, len; |
60 | unsigned char *value; | 61 | unsigned char *value; |
61 | u32 elapsed_time; | 62 | u32 elapsed_time; |
63 | __be32 opt_val; | ||
62 | int rc; | 64 | int rc; |
63 | int mandatory = 0; | 65 | int mandatory = 0; |
64 | 66 | ||
@@ -145,7 +147,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
145 | if (len != 4) | 147 | if (len != 4) |
146 | goto out_invalid_option; | 148 | goto out_invalid_option; |
147 | 149 | ||
148 | opt_recv->dccpor_timestamp = ntohl(*(__be32 *)value); | 150 | opt_val = get_unaligned((__be32 *)value); |
151 | opt_recv->dccpor_timestamp = ntohl(opt_val); | ||
149 | 152 | ||
150 | dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; | 153 | dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; |
151 | dp->dccps_timestamp_time = ktime_get_real(); | 154 | dp->dccps_timestamp_time = ktime_get_real(); |
@@ -159,7 +162,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
159 | if (len != 4 && len != 6 && len != 8) | 162 | if (len != 4 && len != 6 && len != 8) |
160 | goto out_invalid_option; | 163 | goto out_invalid_option; |
161 | 164 | ||
162 | opt_recv->dccpor_timestamp_echo = ntohl(*(__be32 *)value); | 165 | opt_val = get_unaligned((__be32 *)value); |
166 | opt_recv->dccpor_timestamp_echo = ntohl(opt_val); | ||
163 | 167 | ||
164 | dccp_pr_debug("%s rx opt: TIMESTAMP_ECHO=%u, len=%d, " | 168 | dccp_pr_debug("%s rx opt: TIMESTAMP_ECHO=%u, len=%d, " |
165 | "ackno=%llu", dccp_role(sk), | 169 | "ackno=%llu", dccp_role(sk), |
@@ -168,16 +172,20 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
168 | (unsigned long long) | 172 | (unsigned long long) |
169 | DCCP_SKB_CB(skb)->dccpd_ack_seq); | 173 | DCCP_SKB_CB(skb)->dccpd_ack_seq); |
170 | 174 | ||
175 | value += 4; | ||
171 | 176 | ||
172 | if (len == 4) { | 177 | if (len == 4) { /* no elapsed time included */ |
173 | dccp_pr_debug_cat("\n"); | 178 | dccp_pr_debug_cat("\n"); |
174 | break; | 179 | break; |
175 | } | 180 | } |
176 | 181 | ||
177 | if (len == 6) | 182 | if (len == 6) { /* 2-byte elapsed time */ |
178 | elapsed_time = ntohs(*(__be16 *)(value + 4)); | 183 | __be16 opt_val2 = get_unaligned((__be16 *)value); |
179 | else | 184 | elapsed_time = ntohs(opt_val2); |
180 | elapsed_time = ntohl(*(__be32 *)(value + 4)); | 185 | } else { /* 4-byte elapsed time */ |
186 | opt_val = get_unaligned((__be32 *)value); | ||
187 | elapsed_time = ntohl(opt_val); | ||
188 | } | ||
181 | 189 | ||
182 | dccp_pr_debug_cat(", ELAPSED_TIME=%u\n", elapsed_time); | 190 | dccp_pr_debug_cat(", ELAPSED_TIME=%u\n", elapsed_time); |
183 | 191 | ||
@@ -192,10 +200,13 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
192 | if (pkt_type == DCCP_PKT_DATA) | 200 | if (pkt_type == DCCP_PKT_DATA) |
193 | continue; | 201 | continue; |
194 | 202 | ||
195 | if (len == 2) | 203 | if (len == 2) { |
196 | elapsed_time = ntohs(*(__be16 *)value); | 204 | __be16 opt_val2 = get_unaligned((__be16 *)value); |
197 | else | 205 | elapsed_time = ntohs(opt_val2); |
198 | elapsed_time = ntohl(*(__be32 *)value); | 206 | } else { |
207 | opt_val = get_unaligned((__be32 *)value); | ||
208 | elapsed_time = ntohl(opt_val); | ||
209 | } | ||
199 | 210 | ||
200 | if (elapsed_time > opt_recv->dccpor_elapsed_time) | 211 | if (elapsed_time > opt_recv->dccpor_elapsed_time) |
201 | opt_recv->dccpor_elapsed_time = elapsed_time; | 212 | opt_recv->dccpor_elapsed_time = elapsed_time; |