forked from mirrors/linux
		
	af_unix: Clean up error paths in unix_stream_sendmsg().
If we move send_sig() to the SEND_SHUTDOWN check before the while loop, then we can reuse the same kfree_skb() after the pipe_err_free label. Let's gather the scattered kfree_skb()s in error paths. While at it, some style issues are fixed, and the pipe_err_free label is renamed to out_pipe to match other label names. Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
		
							parent
							
								
									6c444255b1
								
							
						
					
					
						commit
						d460b04bc4
					
				
					 1 changed files with 20 additions and 19 deletions
				
			
		|  | @ -2275,8 +2275,13 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) | 	if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) { | ||||||
| 		goto pipe_err; | 		if (!(msg->msg_flags & MSG_NOSIGNAL)) | ||||||
|  | 			send_sig(SIGPIPE, current, 0); | ||||||
|  | 
 | ||||||
|  | 		err = -EPIPE; | ||||||
|  | 		goto out_err; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	while (sent < len) { | 	while (sent < len) { | ||||||
| 		size = len - sent; | 		size = len - sent; | ||||||
|  | @ -2305,20 +2310,18 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, | ||||||
| 
 | 
 | ||||||
| 		/* Only send the fds in the first buffer */ | 		/* Only send the fds in the first buffer */ | ||||||
| 		err = unix_scm_to_skb(&scm, skb, !fds_sent); | 		err = unix_scm_to_skb(&scm, skb, !fds_sent); | ||||||
| 		if (err < 0) { | 		if (err < 0) | ||||||
| 			kfree_skb(skb); | 			goto out_free; | ||||||
| 			goto out_err; | 
 | ||||||
| 		} |  | ||||||
| 		fds_sent = true; | 		fds_sent = true; | ||||||
| 
 | 
 | ||||||
| 		if (unlikely(msg->msg_flags & MSG_SPLICE_PAGES)) { | 		if (unlikely(msg->msg_flags & MSG_SPLICE_PAGES)) { | ||||||
| 			skb->ip_summed = CHECKSUM_UNNECESSARY; | 			skb->ip_summed = CHECKSUM_UNNECESSARY; | ||||||
| 			err = skb_splice_from_iter(skb, &msg->msg_iter, size, | 			err = skb_splice_from_iter(skb, &msg->msg_iter, size, | ||||||
| 						   sk->sk_allocation); | 						   sk->sk_allocation); | ||||||
| 			if (err < 0) { | 			if (err < 0) | ||||||
| 				kfree_skb(skb); | 				goto out_free; | ||||||
| 				goto out_err; | 
 | ||||||
| 			} |  | ||||||
| 			size = err; | 			size = err; | ||||||
| 			refcount_add(size, &sk->sk_wmem_alloc); | 			refcount_add(size, &sk->sk_wmem_alloc); | ||||||
| 		} else { | 		} else { | ||||||
|  | @ -2326,17 +2329,15 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, | ||||||
| 			skb->data_len = data_len; | 			skb->data_len = data_len; | ||||||
| 			skb->len = size; | 			skb->len = size; | ||||||
| 			err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size); | 			err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size); | ||||||
| 			if (err) { | 			if (err) | ||||||
| 				kfree_skb(skb); | 				goto out_free; | ||||||
| 				goto out_err; |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		unix_state_lock(other); | 		unix_state_lock(other); | ||||||
| 
 | 
 | ||||||
| 		if (sock_flag(other, SOCK_DEAD) || | 		if (sock_flag(other, SOCK_DEAD) || | ||||||
| 		    (other->sk_shutdown & RCV_SHUTDOWN)) | 		    (other->sk_shutdown & RCV_SHUTDOWN)) | ||||||
| 			goto pipe_err_free; | 			goto out_pipe; | ||||||
| 
 | 
 | ||||||
| 		maybe_add_creds(skb, sock, other); | 		maybe_add_creds(skb, sock, other); | ||||||
| 		scm_stat_add(other, skb); | 		scm_stat_add(other, skb); | ||||||
|  | @ -2359,13 +2360,13 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, | ||||||
| 
 | 
 | ||||||
| 	return sent; | 	return sent; | ||||||
| 
 | 
 | ||||||
| pipe_err_free: | out_pipe: | ||||||
| 	unix_state_unlock(other); | 	unix_state_unlock(other); | ||||||
| 	kfree_skb(skb); | 	if (!sent && !(msg->msg_flags & MSG_NOSIGNAL)) | ||||||
| pipe_err: |  | ||||||
| 	if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL)) |  | ||||||
| 		send_sig(SIGPIPE, current, 0); | 		send_sig(SIGPIPE, current, 0); | ||||||
| 	err = -EPIPE; | 	err = -EPIPE; | ||||||
|  | out_free: | ||||||
|  | 	kfree_skb(skb); | ||||||
| out_err: | out_err: | ||||||
| 	scm_destroy(&scm); | 	scm_destroy(&scm); | ||||||
| 	return sent ? : err; | 	return sent ? : err; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Kuniyuki Iwashima
						Kuniyuki Iwashima