Bug 15541

Summary: POLLIN bit is set when there is OOB data only
Product: Networking Reporter: Alexandra Kossovsky (Alexandra.Kossovsky)
Component: IPV4Assignee: Stephen Hemminger (stephen)
Status: RESOLVED CODE_FIX    
Severity: normal CC: alan
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 2.6.28, 2.6.32, 2.6.33 Subsystem:
Regression: Yes Bisected commit-id:

Description Alexandra Kossovsky 2010-03-15 16:19:40 UTC
Starting from 2.6.28, Linux kernel has incorrect behaviour when poll() is called on TCP socket with out-of-band byte received.

When TCP socket has OOB byte available (and no normal data), old Linux, Solaris, FreeBSD and other systems return POLLPRI bit without POLLRD.  Starting from 2.6.28, Linux returns POLLRD | POLLPRI | POLLRDNORM.

The broken commt is http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.28.y.git;a=commitdiff;h=c7004482e8dcb7c3c72666395cfa98a216a4fb70 .
Following 1-line patch fixes the problem:
--- a/net/ipv4/tcp.c 2010-03-15 19:13:45.000000000 +0300
+++ b/net/ipv4/tcp.c      2010-03-15 19:13:21.000000000 +0300
@@ -428,7 +428,7 @@
                if (tp->urg_seq == tp->copied_seq &&
                    !sock_flag(sk, SOCK_URGINLINE) &&
                    tp->urg_data)
-                       target--;
+                       target++;

                /* Potential race condition. If read of tp below will
                 * escape above sk->sk_state, we can be illegally awaken
Comment 1 Andrew Morton 2010-03-19 22:56:21 UTC
(switched to email.  Please respond via emailed reply-to-all, not via the
bugzilla web interface).

On Mon, 15 Mar 2010 16:19:43 GMT
bugzilla-daemon@bugzilla.kernel.org wrote:

> http://bugzilla.kernel.org/show_bug.cgi?id=15541
> 
>            Summary: POLLIN bit is set when there is OOB data only
>            Product: Networking
>            Version: 2.5
>     Kernel Version: 2.6.28, 2.6.32, 2.6.33
>           Platform: All
>         OS/Version: Linux
>               Tree: Mainline
>             Status: NEW
>           Severity: normal
>           Priority: P1
>          Component: IPV4
>         AssignedTo: shemminger@linux-foundation.org
>         ReportedBy: Alexandra.Kossovsky@oktetlabs.ru
>                 CC: davem@davemloft.net
>         Regression: Yes
> 
> 
> Starting from 2.6.28, Linux kernel has incorrect behaviour when poll() is
> called on TCP socket with out-of-band byte received.
> 
> When TCP socket has OOB byte available (and no normal data), old Linux,
> Solaris, FreeBSD and other systems return POLLPRI bit without POLLRD. 
> Starting
> from 2.6.28, Linux returns POLLRD | POLLPRI | POLLRDNORM.
> 
> The broken commt is
>
> http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.28.y.git;a=commitdiff;h=c7004482e8dcb7c3c72666395cfa98a216a4fb70
> .
> Following 1-line patch fixes the problem:
> --- a/net/ipv4/tcp.c 2010-03-15 19:13:45.000000000 +0300
> +++ b/net/ipv4/tcp.c      2010-03-15 19:13:21.000000000 +0300
> @@ -428,7 +428,7 @@
>                 if (tp->urg_seq == tp->copied_seq &&
>                     !sock_flag(sk, SOCK_URGINLINE) &&
>                     tp->urg_data)
> -                       target--;
> +                       target++;
> 
>                 /* Potential race condition. If read of tp below will
>                  * escape above sk->sk_state, we can be illegally awaken
> 

Thanks.

(Please don't send patches via bugzilla - it causes lots of problems with
our usual patch management and review processes.

Please send this patch via email as per Documentation/SubmittingPatches. 
Suitable recipients may be found via scripts/get_maintainer.pl)
Comment 2 David S. Miller 2010-03-20 02:43:03 UTC
The patch is already in Linus's tree Andrew.

Stephen Hemminger forwarded this bugzilla entry to netdev
an I applied the patch a few days ago.