Commit 0147fc058d11bd4009b126d09974d2c8f48fef15
Committed by
David S. Miller
1 parent
8475ef9fd1
Exists in
master
and in
4 other branches
tcp: restrict net.ipv4.tcp_adv_win_scale (#20312)
tcp_win_from_space() does the following: if (sysctl_tcp_adv_win_scale <= 0) return space >> (-sysctl_tcp_adv_win_scale); else return space - (space >> sysctl_tcp_adv_win_scale); "space" is int. As per C99 6.5.7 (3) shifting int for 32 or more bits is undefined behaviour. Indeed, if sysctl_tcp_adv_win_scale is exactly 32, space >> 32 equals space and function returns 0. Which means we busyloop in tcp_fixup_rcvbuf(). Restrict net.ipv4.tcp_adv_win_scale to [-31, 31]. Fix https://bugzilla.kernel.org/show_bug.cgi?id=20312 Steps to reproduce: echo 32 >/proc/sys/net/ipv4/tcp_adv_win_scale wget www.kernel.org [softlockup] Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 2 changed files with 6 additions and 1 deletions Side-by-side Diff
Documentation/networking/ip-sysctl.txt
... | ... | @@ -144,6 +144,7 @@ |
144 | 144 | Count buffering overhead as bytes/2^tcp_adv_win_scale |
145 | 145 | (if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale), |
146 | 146 | if it is <= 0. |
147 | + Possible values are [-31, 31], inclusive. | |
147 | 148 | Default: 2 |
148 | 149 | |
149 | 150 | tcp_allowed_congestion_control - STRING |
net/ipv4/sysctl_net_ipv4.c
... | ... | @@ -26,6 +26,8 @@ |
26 | 26 | static int tcp_retr1_max = 255; |
27 | 27 | static int ip_local_port_range_min[] = { 1, 1 }; |
28 | 28 | static int ip_local_port_range_max[] = { 65535, 65535 }; |
29 | +static int tcp_adv_win_scale_min = -31; | |
30 | +static int tcp_adv_win_scale_max = 31; | |
29 | 31 | |
30 | 32 | /* Update system visible IP port range */ |
31 | 33 | static void set_local_port_range(int range[2]) |
... | ... | @@ -426,7 +428,9 @@ |
426 | 428 | .data = &sysctl_tcp_adv_win_scale, |
427 | 429 | .maxlen = sizeof(int), |
428 | 430 | .mode = 0644, |
429 | - .proc_handler = proc_dointvec | |
431 | + .proc_handler = proc_dointvec_minmax, | |
432 | + .extra1 = &tcp_adv_win_scale_min, | |
433 | + .extra2 = &tcp_adv_win_scale_max, | |
430 | 434 | }, |
431 | 435 | { |
432 | 436 | .procname = "tcp_tw_reuse", |