| From 0e5ea9ad3898d14e4a750ee35569502e3cf1a58a Mon Sep 17 00:00:00 2001 |
| From: Ilpo Jรคrvinen <ilpo.jarvinen@helsinki.fi> |
| Date: Sun, 10 May 2009 20:32:34 +0000 |
| Subject: tcp: fix MSG_PEEK race check |
| |
| From: Ilpo Jarvinen <ilpo.jarvinen@helsinki.fi> |
| |
| [ Upstream commit 775273131810caa41dfc7f9e552ea5d8508caf40 ] |
| |
| Commit 518a09ef11 (tcp: Fix recvmsg MSG_PEEK influence of |
| blocking behavior) lets the loop run longer than the race check |
| did previously expect, so we need to be more careful with this |
| check and consider the work we have been doing. |
| |
| I tried my best to deal with urg hole madness too which happens |
| here: |
| if (!sock_flag(sk, SOCK_URGINLINE)) { |
| ++*seq; |
| ... |
| by using additional offset by one but I certainly have very |
| little interest in testing that part. |
| |
| Signed-off-by: Ilpo Jarvinen <ilpo.jarvinen@helsinki.fi> |
| Tested-by: Frans Pop <elendil@planet.nl> |
| Tested-by: Ian Zimmermann <itz@buug.org> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| net/ipv4/tcp.c | 5 ++++- |
| 1 file changed, 4 insertions(+), 1 deletion(-) |
| |
| --- a/net/ipv4/tcp.c |
| +++ b/net/ipv4/tcp.c |
| @@ -1286,6 +1286,7 @@ int tcp_recvmsg(struct kiocb *iocb, stru |
| struct task_struct *user_recv = NULL; |
| int copied_early = 0; |
| struct sk_buff *skb; |
| + u32 urg_hole = 0; |
| |
| lock_sock(sk); |
| |
| @@ -1497,7 +1498,8 @@ do_prequeue: |
| } |
| } |
| } |
| - if ((flags & MSG_PEEK) && peek_seq != tp->copied_seq) { |
| + if ((flags & MSG_PEEK) && |
| + (peek_seq - copied - urg_hole != tp->copied_seq)) { |
| if (net_ratelimit()) |
| printk(KERN_DEBUG "TCP(%s:%d): Application bug, race in MSG_PEEK.\n", |
| current->comm, task_pid_nr(current)); |
| @@ -1518,6 +1520,7 @@ do_prequeue: |
| if (!urg_offset) { |
| if (!sock_flag(sk, SOCK_URGINLINE)) { |
| ++*seq; |
| + urg_hole++; |
| offset++; |
| used--; |
| if (!used) |