tcp: restrict net.ipv4.tcp_adv_win_scale (#20312)
authorAlexey Dobriyan <adobriyan@gmail.com>
Mon, 22 Nov 2010 12:54:21 +0000 (12:54 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sun, 28 Nov 2010 18:39:45 +0000 (10:39 -0800)
commit0147fc058d11bd4009b126d09974d2c8f48fef15
treef73f0e82f7774938dd7190c6a810e0ccb2466f2b
parent8475ef9fd16cadbfc692f78e608d1941a340beb2
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>
Documentation/networking/ip-sysctl.txt
net/ipv4/sysctl_net_ipv4.c