Skip to content

Commit e83c674

Browse files
Eric Dumazetdavem330
authored andcommitted
udp: fix poll() issue with zero sized packets
Laura tracked poll() [and friends] regression caused by commit e6afc8a ("udp: remove headers from UDP packets before queueing") udp_poll() needs to know if there is a valid packet in receive queue, even if its payload length is 0. Change first_packet_length() to return an signed int, and use -1 as the indication of an empty queue. Fixes: e6afc8a ("udp: remove headers from UDP packets before queueing") Reported-by: Laura Abbott <[email protected]> Signed-off-by: Eric Dumazet <[email protected]> Tested-by: Laura Abbott <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 28a10c4 commit e83c674

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

net/ipv4/udp.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,13 +1182,13 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset,
11821182
* @sk: socket
11831183
*
11841184
* Drops all bad checksum frames, until a valid one is found.
1185-
* Returns the length of found skb, or 0 if none is found.
1185+
* Returns the length of found skb, or -1 if none is found.
11861186
*/
1187-
static unsigned int first_packet_length(struct sock *sk)
1187+
static int first_packet_length(struct sock *sk)
11881188
{
11891189
struct sk_buff_head list_kill, *rcvq = &sk->sk_receive_queue;
11901190
struct sk_buff *skb;
1191-
unsigned int res;
1191+
int res;
11921192

11931193
__skb_queue_head_init(&list_kill);
11941194

@@ -1203,7 +1203,7 @@ static unsigned int first_packet_length(struct sock *sk)
12031203
__skb_unlink(skb, rcvq);
12041204
__skb_queue_tail(&list_kill, skb);
12051205
}
1206-
res = skb ? skb->len : 0;
1206+
res = skb ? skb->len : -1;
12071207
spin_unlock_bh(&rcvq->lock);
12081208

12091209
if (!skb_queue_empty(&list_kill)) {
@@ -1232,7 +1232,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
12321232

12331233
case SIOCINQ:
12341234
{
1235-
unsigned int amount = first_packet_length(sk);
1235+
int amount = max_t(int, 0, first_packet_length(sk));
12361236

12371237
return put_user(amount, (int __user *)arg);
12381238
}
@@ -2184,7 +2184,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
21842184

21852185
/* Check for false positives due to checksum errors */
21862186
if ((mask & POLLRDNORM) && !(file->f_flags & O_NONBLOCK) &&
2187-
!(sk->sk_shutdown & RCV_SHUTDOWN) && !first_packet_length(sk))
2187+
!(sk->sk_shutdown & RCV_SHUTDOWN) && first_packet_length(sk) == -1)
21882188
mask &= ~(POLLIN | POLLRDNORM);
21892189

21902190
return mask;

0 commit comments

Comments
 (0)