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/ipv4/tcp_ipv4.c | |
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/ipv4/tcp_ipv4.c')
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 36 |
1 files changed, 25 insertions, 11 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)) |