diff options
Diffstat (limited to 'net/ipv4')
| -rw-r--r-- | net/ipv4/tcp.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f88653138621..ab66683b8043 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -1227,7 +1227,14 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, | |||
| 1227 | copied += used; | 1227 | copied += used; |
| 1228 | offset += used; | 1228 | offset += used; |
| 1229 | } | 1229 | } |
| 1230 | if (offset != skb->len) | 1230 | /* |
| 1231 | * If recv_actor drops the lock (e.g. TCP splice | ||
| 1232 | * receive) the skb pointer might be invalid when | ||
| 1233 | * getting here: tcp_collapse might have deleted it | ||
| 1234 | * while aggregating skbs from the socket queue. | ||
| 1235 | */ | ||
| 1236 | skb = tcp_recv_skb(sk, seq-1, &offset); | ||
| 1237 | if (!skb || (offset+1 != skb->len)) | ||
| 1231 | break; | 1238 | break; |
| 1232 | } | 1239 | } |
| 1233 | if (tcp_hdr(skb)->fin) { | 1240 | if (tcp_hdr(skb)->fin) { |
