diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2010-11-22 12:54:21 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-11-28 10:39:45 -0800 |
commit | 0147fc058d11bd4009b126d09974d2c8f48fef15 (patch) | |
tree | f73f0e82f7774938dd7190c6a810e0ccb2466f2b /Documentation/networking | |
parent | 8475ef9fd16cadbfc692f78e608d1941a340beb2 (diff) | |
download | linux-0147fc058d11bd4009b126d09974d2c8f48fef15.tar.gz linux-0147fc058d11bd4009b126d09974d2c8f48fef15.tar.bz2 linux-0147fc058d11bd4009b126d09974d2c8f48fef15.zip |
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>
Diffstat (limited to 'Documentation/networking')
-rw-r--r-- | Documentation/networking/ip-sysctl.txt | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index fe95105992c5..3c5e465296e1 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -144,6 +144,7 @@ tcp_adv_win_scale - INTEGER Count buffering overhead as bytes/2^tcp_adv_win_scale (if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale), if it is <= 0. + Possible values are [-31, 31], inclusive. Default: 2 tcp_allowed_congestion_control - STRING |