Skip to content

Commit 909172a

Browse files
Mao Wenankuba-moo
authored andcommitted
net: Update window_clamp if SOCK_RCVBUF is set
When net.ipv4.tcp_syncookies=1 and syn flood is happened, cookie_v4_check or cookie_v6_check tries to redo what tcp_v4_send_synack or tcp_v6_send_synack did, rsk_window_clamp will be changed if SOCK_RCVBUF is set, which will make rcv_wscale is different, the client still operates with initial window scale and can overshot granted window, the client use the initial scale but local server use new scale to advertise window value, and session work abnormally. Fixes: e88c64f ("tcp: allow effective reduction of TCP's rcv-buffer via setsockopt") Signed-off-by: Mao Wenan <wenan.mao@linux.alibaba.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://lore.kernel.org/r/1604967391-123737-1-git-send-email-wenan.mao@linux.alibaba.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent f3037c5 commit 909172a

2 files changed

Lines changed: 15 additions & 4 deletions

File tree

net/ipv4/syncookies.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
331331
__u32 cookie = ntohl(th->ack_seq) - 1;
332332
struct sock *ret = sk;
333333
struct request_sock *req;
334-
int mss;
334+
int full_space, mss;
335335
struct rtable *rt;
336336
__u8 rcv_wscale;
337337
struct flowi4 fl4;
@@ -427,8 +427,13 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
427427

428428
/* Try to redo what tcp_v4_send_synack did. */
429429
req->rsk_window_clamp = tp->window_clamp ? :dst_metric(&rt->dst, RTAX_WINDOW);
430+
/* limit the window selection if the user enforce a smaller rx buffer */
431+
full_space = tcp_full_space(sk);
432+
if (sk->sk_userlocks & SOCK_RCVBUF_LOCK &&
433+
(req->rsk_window_clamp > full_space || req->rsk_window_clamp == 0))
434+
req->rsk_window_clamp = full_space;
430435

431-
tcp_select_initial_window(sk, tcp_full_space(sk), req->mss,
436+
tcp_select_initial_window(sk, full_space, req->mss,
432437
&req->rsk_rcv_wnd, &req->rsk_window_clamp,
433438
ireq->wscale_ok, &rcv_wscale,
434439
dst_metric(&rt->dst, RTAX_INITRWND));

net/ipv6/syncookies.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
136136
__u32 cookie = ntohl(th->ack_seq) - 1;
137137
struct sock *ret = sk;
138138
struct request_sock *req;
139-
int mss;
139+
int full_space, mss;
140140
struct dst_entry *dst;
141141
__u8 rcv_wscale;
142142
u32 tsoff = 0;
@@ -241,7 +241,13 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
241241
}
242242

243243
req->rsk_window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW);
244-
tcp_select_initial_window(sk, tcp_full_space(sk), req->mss,
244+
/* limit the window selection if the user enforce a smaller rx buffer */
245+
full_space = tcp_full_space(sk);
246+
if (sk->sk_userlocks & SOCK_RCVBUF_LOCK &&
247+
(req->rsk_window_clamp > full_space || req->rsk_window_clamp == 0))
248+
req->rsk_window_clamp = full_space;
249+
250+
tcp_select_initial_window(sk, full_space, req->mss,
245251
&req->rsk_rcv_wnd, &req->rsk_window_clamp,
246252
ireq->wscale_ok, &rcv_wscale,
247253
dst_metric(dst, RTAX_INITRWND));

0 commit comments

Comments
 (0)