Re: [058/152] tcp: protect sysctl_tcp_cookie_size reads

William Allen Simpson
2011-01-07T04:08:58Z

Thank you for bringing this to my attention. There's been quite a few
changes in the 18 months since this function was originally written.

The overall purpose of the patch seems OK, although most of the patch
has nothing to do with the purported fix.

That is, somebody preferred to alter conditions and remove braces. Seems
harder to read to me! I'm surprised that this passed checkpatch.pl?

On 1/5/11 7:22 PM, Greg KH wrote:
> 2.6.36-stable review patch. If anyone has any objections, please let us know.
>
> ------------------
>
>
> From: Eric Dumazet<eric.dumazet@gmail.com>
>
> [ Upstream commit f19872575ff7819a3723154657a497d9bca66b33 ]
>
> Make sure sysctl_tcp_cookie_size is read once in
> tcp_cookie_size_check(), or we might return an illegal value to caller
> if sysctl_tcp_cookie_size is changed by another cpu.
>
> Signed-off-by: Eric Dumazet<eric.dumazet@gmail.com>
> Cc: Ben Hutchings<bhutchings@solarflare.com>
> Cc: William Allen Simpson<william.allen.simpson@gmail.com>
> Signed-off-by: David S. Miller<davem@davemloft.net>
> Signed-off-by: Greg Kroah-Hartman<gregkh@suse.de>
> ---
> net/ipv4/tcp_output.c | 27 +++++++++++++++------------
> 1 file changed, 15 insertions(+), 12 deletions(-)
>
> --- a/net/ipv4/tcp_output.c
> +++ b/net/ipv4/tcp_output.c
> @@ -391,27 +391,30 @@ struct tcp_out_options {
> */
> static u8 tcp_cookie_size_check(u8 desired)
> {
> - if (desired> 0) {
> + int cookie_size;
> +
> + if (desired> 0)
> /* previously specified */
> return desired;
> - }
> - if (sysctl_tcp_cookie_size<= 0) {
> +
> + cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size);
> + if (cookie_size<= 0)
> /* no default specified */
> return 0;
> - }
> - if (sysctl_tcp_cookie_size<= TCP_COOKIE_MIN) {
> +
> + if (cookie_size<= TCP_COOKIE_MIN)
> /* value too small, specify minimum */
> return TCP_COOKIE_MIN;
> - }
> - if (sysctl_tcp_cookie_size>= TCP_COOKIE_MAX) {
> +
> + if (cookie_size>= TCP_COOKIE_MAX)
> /* value too large, specify maximum */
> return TCP_COOKIE_MAX;
> - }
> - if (0x1& sysctl_tcp_cookie_size) {
> +
> + if (cookie_size& 1)
> /* 8-bit multiple, illegal, fix it */
> - return (u8)(sysctl_tcp_cookie_size + 0x1);
> - }
> - return (u8)sysctl_tcp_cookie_size;
> + cookie_size++;
> +
> + return (u8)cookie_size;
> }
>
> /* Write previously computed TCP options to the packet.
>
>
>