diff options
| -rw-r--r-- | net/dccp/ccids/ccid3.c | 11 | ||||
| -rw-r--r-- | net/dccp/options.c | 33 |
2 files changed, 29 insertions, 15 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 25772c326172..05f263e9160d 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
| @@ -40,6 +40,8 @@ | |||
| 40 | #include "lib/tfrc.h" | 40 | #include "lib/tfrc.h" |
| 41 | #include "ccid3.h" | 41 | #include "ccid3.h" |
| 42 | 42 | ||
| 43 | #include <asm/unaligned.h> | ||
| 44 | |||
| 43 | #ifdef CONFIG_IP_DCCP_CCID3_DEBUG | 45 | #ifdef CONFIG_IP_DCCP_CCID3_DEBUG |
| 44 | static int ccid3_debug; | 46 | static int ccid3_debug; |
| 45 | #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a) | 47 | #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a) |
| @@ -544,6 +546,7 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, | |||
| 544 | const struct dccp_sock *dp = dccp_sk(sk); | 546 | const struct dccp_sock *dp = dccp_sk(sk); |
| 545 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); | 547 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); |
| 546 | struct ccid3_options_received *opt_recv; | 548 | struct ccid3_options_received *opt_recv; |
| 549 | __be32 opt_val; | ||
| 547 | 550 | ||
| 548 | opt_recv = &hctx->ccid3hctx_options_received; | 551 | opt_recv = &hctx->ccid3hctx_options_received; |
| 549 | 552 | ||
| @@ -563,8 +566,8 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, | |||
| 563 | dccp_role(sk), sk, len); | 566 | dccp_role(sk), sk, len); |
| 564 | rc = -EINVAL; | 567 | rc = -EINVAL; |
| 565 | } else { | 568 | } else { |
| 566 | opt_recv->ccid3or_loss_event_rate = | 569 | opt_val = get_unaligned((__be32 *)value); |
| 567 | ntohl(*(__be32 *)value); | 570 | opt_recv->ccid3or_loss_event_rate = ntohl(opt_val); |
| 568 | ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n", | 571 | ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n", |
| 569 | dccp_role(sk), sk, | 572 | dccp_role(sk), sk, |
| 570 | opt_recv->ccid3or_loss_event_rate); | 573 | opt_recv->ccid3or_loss_event_rate); |
| @@ -585,8 +588,8 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, | |||
| 585 | dccp_role(sk), sk, len); | 588 | dccp_role(sk), sk, len); |
| 586 | rc = -EINVAL; | 589 | rc = -EINVAL; |
| 587 | } else { | 590 | } else { |
| 588 | opt_recv->ccid3or_receive_rate = | 591 | opt_val = get_unaligned((__be32 *)value); |
| 589 | ntohl(*(__be32 *)value); | 592 | opt_recv->ccid3or_receive_rate = ntohl(opt_val); |
| 590 | ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n", | 593 | ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n", |
| 591 | dccp_role(sk), sk, | 594 | dccp_role(sk), sk, |
| 592 | opt_recv->ccid3or_receive_rate); | 595 | opt_recv->ccid3or_receive_rate); |
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; |
