diff options
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 36 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 25 |
2 files changed, 44 insertions, 17 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 992a1f926009..dceff5fe8e66 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -1167,7 +1167,8 @@ clear_hash_noput: | |||
| 1167 | } | 1167 | } |
| 1168 | EXPORT_SYMBOL(tcp_v4_md5_hash_skb); | 1168 | EXPORT_SYMBOL(tcp_v4_md5_hash_skb); |
| 1169 | 1169 | ||
| 1170 | static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) | 1170 | static bool __tcp_v4_inbound_md5_hash(struct sock *sk, |
| 1171 | const struct sk_buff *skb) | ||
| 1171 | { | 1172 | { |
| 1172 | /* | 1173 | /* |
| 1173 | * This gets called for each TCP segment that arrives | 1174 | * This gets called for each TCP segment that arrives |
| @@ -1220,6 +1221,17 @@ static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) | |||
| 1220 | return false; | 1221 | return false; |
| 1221 | } | 1222 | } |
| 1222 | 1223 | ||
| 1224 | static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) | ||
| 1225 | { | ||
| 1226 | bool ret; | ||
| 1227 | |||
| 1228 | rcu_read_lock(); | ||
| 1229 | ret = __tcp_v4_inbound_md5_hash(sk, skb); | ||
| 1230 | rcu_read_unlock(); | ||
| 1231 | |||
| 1232 | return ret; | ||
| 1233 | } | ||
| 1234 | |||
| 1223 | #endif | 1235 | #endif |
| 1224 | 1236 | ||
| 1225 | static void tcp_v4_init_req(struct request_sock *req, struct sock *sk, | 1237 | static void tcp_v4_init_req(struct request_sock *req, struct sock *sk, |
| @@ -1432,16 +1444,6 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) | |||
| 1432 | int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) | 1444 | int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) |
| 1433 | { | 1445 | { |
| 1434 | struct sock *rsk; | 1446 | struct sock *rsk; |
| 1435 | #ifdef CONFIG_TCP_MD5SIG | ||
| 1436 | /* | ||
| 1437 | * We really want to reject the packet as early as possible | ||
| 1438 | * if: | ||
| 1439 | * o We're expecting an MD5'd packet and this is no MD5 tcp option | ||
| 1440 | * o There is an MD5 option and we're not expecting one | ||
| 1441 | */ | ||
| 1442 | if (tcp_v4_inbound_md5_hash(sk, skb)) | ||
| 1443 | goto discard; | ||
| 1444 | #endif | ||
| 1445 | 1447 | ||
| 1446 | if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ | 1448 | if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ |
| 1447 | struct dst_entry *dst = sk->sk_rx_dst; | 1449 | struct dst_entry *dst = sk->sk_rx_dst; |
| @@ -1644,6 +1646,18 @@ process: | |||
| 1644 | 1646 | ||
| 1645 | if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) | 1647 | if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) |
| 1646 | goto discard_and_relse; | 1648 | goto discard_and_relse; |
| 1649 | |||
| 1650 | #ifdef CONFIG_TCP_MD5SIG | ||
| 1651 | /* | ||
| 1652 | * We really want to reject the packet as early as possible | ||
| 1653 | * if: | ||
| 1654 | * o We're expecting an MD5'd packet and this is no MD5 tcp option | ||
| 1655 | * o There is an MD5 option and we're not expecting one | ||
| 1656 | */ | ||
| 1657 | if (tcp_v4_inbound_md5_hash(sk, skb)) | ||
| 1658 | goto discard_and_relse; | ||
| 1659 | #endif | ||
| 1660 | |||
| 1647 | nf_reset(skb); | 1661 | nf_reset(skb); |
| 1648 | 1662 | ||
| 1649 | if (sk_filter(sk, skb)) | 1663 | if (sk_filter(sk, skb)) |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 22055b098428..f2ce95502392 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -667,7 +667,8 @@ clear_hash_noput: | |||
| 667 | return 1; | 667 | return 1; |
| 668 | } | 668 | } |
| 669 | 669 | ||
| 670 | static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) | 670 | static int __tcp_v6_inbound_md5_hash(struct sock *sk, |
| 671 | const struct sk_buff *skb) | ||
| 671 | { | 672 | { |
| 672 | const __u8 *hash_location = NULL; | 673 | const __u8 *hash_location = NULL; |
| 673 | struct tcp_md5sig_key *hash_expected; | 674 | struct tcp_md5sig_key *hash_expected; |
| @@ -707,6 +708,18 @@ static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) | |||
| 707 | } | 708 | } |
| 708 | return 0; | 709 | return 0; |
| 709 | } | 710 | } |
| 711 | |||
| 712 | static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) | ||
| 713 | { | ||
| 714 | int ret; | ||
| 715 | |||
| 716 | rcu_read_lock(); | ||
| 717 | ret = __tcp_v6_inbound_md5_hash(sk, skb); | ||
| 718 | rcu_read_unlock(); | ||
| 719 | |||
| 720 | return ret; | ||
| 721 | } | ||
| 722 | |||
| 710 | #endif | 723 | #endif |
| 711 | 724 | ||
| 712 | static void tcp_v6_init_req(struct request_sock *req, struct sock *sk, | 725 | static void tcp_v6_init_req(struct request_sock *req, struct sock *sk, |
| @@ -1247,11 +1260,6 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 1247 | if (skb->protocol == htons(ETH_P_IP)) | 1260 | if (skb->protocol == htons(ETH_P_IP)) |
| 1248 | return tcp_v4_do_rcv(sk, skb); | 1261 | return tcp_v4_do_rcv(sk, skb); |
| 1249 | 1262 | ||
| 1250 | #ifdef CONFIG_TCP_MD5SIG | ||
| 1251 | if (tcp_v6_inbound_md5_hash(sk, skb)) | ||
| 1252 | goto discard; | ||
| 1253 | #endif | ||
| 1254 | |||
| 1255 | if (sk_filter(sk, skb)) | 1263 | if (sk_filter(sk, skb)) |
| 1256 | goto discard; | 1264 | goto discard; |
| 1257 | 1265 | ||
| @@ -1424,6 +1432,11 @@ process: | |||
| 1424 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) | 1432 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) |
| 1425 | goto discard_and_relse; | 1433 | goto discard_and_relse; |
| 1426 | 1434 | ||
| 1435 | #ifdef CONFIG_TCP_MD5SIG | ||
| 1436 | if (tcp_v6_inbound_md5_hash(sk, skb)) | ||
| 1437 | goto discard_and_relse; | ||
| 1438 | #endif | ||
| 1439 | |||
| 1427 | if (sk_filter(sk, skb)) | 1440 | if (sk_filter(sk, skb)) |
| 1428 | goto discard_and_relse; | 1441 | goto discard_and_relse; |
| 1429 | 1442 | ||
