mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-01 10:43:43 +00:00
af_unix: Remove dead code in unix_stream_read_generic().
When splice() support was added in commit2b514574f7
("net: af_unix: implement splice for stream af_unix sockets"), we had to release unix_sk(sk)->readlock (current iolock) before calling splice_to_pipe(). Due to the unlock, commit73ed5d25dc
("af-unix: fix use-after-free with concurrent readers while splicing") added a safeguard in unix_stream_read_generic(); we had to bump the skb refcount before calling ->recv_actor() and then check if the skb was consumed by a concurrent reader. However, the pipe side locking was refactored, and since commit25869262ef
("skb_splice_bits(): get rid of callback"), we can call splice_to_pipe() without releasing unix_sk(sk)->iolock. Now, the skb is always alive after the ->recv_actor() callback, so let's remove the unnecessary drop_skb logic. This is mostly the revert of commit73ed5d25dc
("af-unix: fix use-after-free with concurrent readers while splicing"). Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> Link: https://lore.kernel.org/r/20240529144648.68591-1-kuniyu@amazon.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
750ed239bf
commit
b5c0898807
@ -654,8 +654,8 @@ static void unix_release_sock(struct sock *sk, int embrion)
|
||||
while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
|
||||
if (state == TCP_LISTEN)
|
||||
unix_release_sock(skb->sk, 1);
|
||||
|
||||
/* passed fds are erased in the kfree_skb hook */
|
||||
UNIXCB(skb).consumed = skb->len;
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
@ -2704,9 +2704,8 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
|
||||
skip = max(sk_peek_offset(sk, flags), 0);
|
||||
|
||||
do {
|
||||
int chunk;
|
||||
bool drop_skb;
|
||||
struct sk_buff *skb, *last;
|
||||
int chunk;
|
||||
|
||||
redo:
|
||||
unix_state_lock(sk);
|
||||
@ -2802,11 +2801,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
|
||||
}
|
||||
|
||||
chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size);
|
||||
skb_get(skb);
|
||||
chunk = state->recv_actor(skb, skip, chunk, state);
|
||||
drop_skb = !unix_skb_len(skb);
|
||||
/* skb is only safe to use if !drop_skb */
|
||||
consume_skb(skb);
|
||||
if (chunk < 0) {
|
||||
if (copied == 0)
|
||||
copied = -EFAULT;
|
||||
@ -2815,18 +2810,6 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
|
||||
copied += chunk;
|
||||
size -= chunk;
|
||||
|
||||
if (drop_skb) {
|
||||
/* the skb was touched by a concurrent reader;
|
||||
* we should not expect anything from this skb
|
||||
* anymore and assume it invalid - we can be
|
||||
* sure it was dropped from the socket queue
|
||||
*
|
||||
* let's report a short read
|
||||
*/
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Mark read part of skb as used */
|
||||
if (!(flags & MSG_PEEK)) {
|
||||
UNIXCB(skb).consumed += chunk;
|
||||
|
Loading…
Reference in New Issue
Block a user