diff options
author | Dmitry Popov <ixaphire@qrator.net> | 2014-08-06 18:38:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-08-06 19:00:20 -0400 |
commit | 9ea88a153001ffeb3d8810917e8eea62ca9b6f25 (patch) | |
tree | 5e0139567bed202fc110fbe1e78febe385f410ca /net/ipv6 | |
parent | 269f8cb2608c7bdebadeb9a2061ba42dcd6d4ff7 (diff) |
tcp: md5: check md5 signature without socket lock
Since a8afca032 (tcp: md5: protects md5sig_info with RCU) tcp_md5_do_lookup
doesn't require socket lock, rcu_read_lock is enough. Therefore socket lock is
no longer required for tcp_v{4,6}_inbound_md5_hash too, so we can move these
calls (wrapped with rcu_read_{,un}lock) before bh_lock_sock:
from tcp_v{4,6}_do_rcv to tcp_v{4,6}_rcv.
Signed-off-by: Dmitry Popov <ixaphire@qrator.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 25 |
1 files changed, 19 insertions, 6 deletions
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 | ||