mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
Merge branch 'rxrpc-miscellaneous-fixes'
David Howells says:
====================
rxrpc: Miscellaneous fixes
Here are some miscellaneous AF_RXRPC fixes:
(1) Make sure rxrpc_verify_data() allocates a buffer, even if the DATA
packet being looked at is zero length to avoid potential NULL-pointer
exceptions.
(2) Don't move an OOB message (e.g. an RxGK CHALLENGE) off the receive
queue onto the pending queue in recvmsg() if MSG_PEEK is specified.
(3) Fix a potential UAF in rxgk_issue_challenge() in which a tracepoint
refers to memory just freed by a different pointer.
(4) Fix afs net namespace teardown to cancel the incoming call
preallocation charger before we disable listening (which will delete
the preallocation queue).
(5) Fix rxrpc_kernel_charge_accept() to use the socket mutex to defend
against listen(0)/shutdown simultaneously deleting the preallocation
queue.
====================
Link: https://patch.msgid.link/20260609140911.838677-1-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
344873108c
|
|
@ -127,6 +127,7 @@ void afs_close_socket(struct afs_net *net)
|
|||
{
|
||||
_enter("");
|
||||
|
||||
cancel_work_sync(&net->charge_preallocation_work);
|
||||
kernel_listen(net->socket, 0);
|
||||
flush_workqueue(afs_async_calls);
|
||||
|
||||
|
|
@ -742,7 +743,7 @@ void afs_charge_preallocation(struct work_struct *work)
|
|||
container_of(work, struct afs_net, charge_preallocation_work);
|
||||
struct afs_call *call = net->spare_incoming_call;
|
||||
|
||||
for (;;) {
|
||||
while (READ_ONCE(net->live)) {
|
||||
if (!call) {
|
||||
call = afs_alloc_call(net, &afs_RXCMxxxx, GFP_KERNEL);
|
||||
if (!call)
|
||||
|
|
@ -792,7 +793,8 @@ static void afs_rx_new_call(struct sock *sk, struct rxrpc_call *rxcall,
|
|||
if (!call->server)
|
||||
trace_afs_cm_no_server(call, rxrpc_kernel_remote_srx(call->peer));
|
||||
|
||||
queue_work(afs_wq, &net->charge_preallocation_work);
|
||||
if (net->live)
|
||||
queue_work(afs_wq, &net->charge_preallocation_work);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -471,13 +471,26 @@ int rxrpc_kernel_charge_accept(struct socket *sock, rxrpc_notify_rx_t notify_rx,
|
|||
unsigned long user_call_ID, gfp_t gfp,
|
||||
unsigned int debug_id)
|
||||
{
|
||||
struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
|
||||
struct rxrpc_backlog *b = rx->backlog;
|
||||
struct rxrpc_backlog *b;
|
||||
struct rxrpc_sock *rx;
|
||||
struct sock *sk;
|
||||
int ret;
|
||||
|
||||
if (sock->sk->sk_state == RXRPC_CLOSE)
|
||||
return -ESHUTDOWN;
|
||||
sk = sock->sk;
|
||||
rx = rxrpc_sk(sk);
|
||||
|
||||
return rxrpc_service_prealloc_one(rx, b, notify_rx, user_call_ID,
|
||||
gfp, debug_id);
|
||||
lock_sock(sk);
|
||||
if (sk->sk_state != RXRPC_SERVER_LISTENING || !rx->backlog) {
|
||||
ret = -ESHUTDOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
b = rx->backlog;
|
||||
ret = rxrpc_service_prealloc_one(rx, b, notify_rx, user_call_ID,
|
||||
gfp, debug_id);
|
||||
|
||||
out:
|
||||
release_sock(sk);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(rxrpc_kernel_charge_accept);
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ static int rxrpc_verify_data(struct rxrpc_call *call, struct sk_buff *skb)
|
|||
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
|
||||
int ret;
|
||||
|
||||
if (sp->len > call->rx_dec_bsize) {
|
||||
if (sp->len > call->rx_dec_bsize || !call->rx_dec_buffer) {
|
||||
/* Make sure we can hold a 1412-byte jumbo subpacket and make
|
||||
* sure that the buffer size is aligned to a crypto blocksize.
|
||||
*/
|
||||
|
|
@ -262,12 +262,13 @@ static int rxrpc_recvmsg_oob(struct socket *sock, struct msghdr *msg,
|
|||
break;
|
||||
}
|
||||
|
||||
if (!(flags & MSG_PEEK))
|
||||
if (!(flags & MSG_PEEK)) {
|
||||
skb_unlink(skb, &rx->recvmsg_oobq);
|
||||
if (need_response)
|
||||
rxrpc_add_pending_oob(rx, skb);
|
||||
else
|
||||
rxrpc_free_skb(skb, rxrpc_skb_put_oob);
|
||||
if (need_response)
|
||||
rxrpc_add_pending_oob(rx, skb);
|
||||
else
|
||||
rxrpc_free_skb(skb, rxrpc_skb_put_oob);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -687,16 +687,17 @@ static int rxgk_issue_challenge(struct rxrpc_connection *conn)
|
|||
ret = do_udp_sendmsg(conn->local->socket, &msg, len);
|
||||
if (ret > 0)
|
||||
rxrpc_peer_mark_tx(conn->peer);
|
||||
__free_page(page);
|
||||
|
||||
if (ret < 0) {
|
||||
trace_rxrpc_tx_fail(conn->debug_id, serial, ret,
|
||||
rxrpc_tx_point_rxgk_challenge);
|
||||
__free_page(page);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
trace_rxrpc_tx_packet(conn->debug_id, whdr,
|
||||
rxrpc_tx_point_rxgk_challenge);
|
||||
__free_page(page);
|
||||
_leave(" = 0");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user