aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/options.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/options.c')
-rw-r--r--net/dccp/options.c33
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;