Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 166c8818 authored by David S. Miller's avatar David S. Miller
Browse files


David Howells says:

====================
rxrpc: Fixes

Here are some patches that fix some things in AF_RXRPC:

 (1) Prevent notifications from being passed to a kernel service for a call
     that it has ended.

 (2) Fix a null pointer deference that occurs under some circumstances when an
     ACK is generated.

 (3) Fix a number of things to do with call expiration.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 442866ff dcbefc30
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -322,6 +322,14 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
}
EXPORT_SYMBOL(rxrpc_kernel_begin_call);

/*
 * Dummy function used to stop the notifier talking to recvmsg().
 */
static void rxrpc_dummy_notify_rx(struct sock *sk, struct rxrpc_call *rxcall,
				  unsigned long call_user_ID)
{
}

/**
 * rxrpc_kernel_end_call - Allow a kernel service to end a call it was using
 * @sock: The socket the call is on
@@ -336,6 +344,14 @@ void rxrpc_kernel_end_call(struct socket *sock, struct rxrpc_call *call)

	mutex_lock(&call->user_mutex);
	rxrpc_release_call(rxrpc_sk(sock->sk), call);

	/* Make sure we're not going to call back into a kernel service */
	if (call->notify_rx) {
		spin_lock_bh(&call->notify_lock);
		call->notify_rx = rxrpc_dummy_notify_rx;
		spin_unlock_bh(&call->notify_lock);
	}

	mutex_unlock(&call->user_mutex);
	rxrpc_put_call(call, rxrpc_call_put_kernel);
}
+1 −0
Original line number Diff line number Diff line
@@ -525,6 +525,7 @@ struct rxrpc_call {
	unsigned long		flags;
	unsigned long		events;
	spinlock_t		lock;
	spinlock_t		notify_lock;	/* Kernel notification lock */
	rwlock_t		state_lock;	/* lock for state transition */
	u32			abort_code;	/* Local/remote abort code */
	int			error;		/* Local error incurred */
+1 −1
Original line number Diff line number Diff line
@@ -386,7 +386,7 @@ void rxrpc_process_call(struct work_struct *work)

	now = ktime_get_real();
	if (ktime_before(call->expire_at, now)) {
		rxrpc_abort_call("EXP", call, 0, RX_CALL_TIMEOUT, -ETIME);
		rxrpc_abort_call("EXP", call, 0, RX_USER_ABORT, -ETIME);
		set_bit(RXRPC_CALL_EV_ABORT, &call->events);
		goto recheck_state;
	}
+1 −0
Original line number Diff line number Diff line
@@ -124,6 +124,7 @@ struct rxrpc_call *rxrpc_alloc_call(gfp_t gfp)
	INIT_LIST_HEAD(&call->sock_link);
	init_waitqueue_head(&call->waitq);
	spin_lock_init(&call->lock);
	spin_lock_init(&call->notify_lock);
	rwlock_init(&call->state_lock);
	atomic_set(&call->usage, 1);
	call->debug_id = atomic_inc_return(&rxrpc_debug_id);
+0 −2
Original line number Diff line number Diff line
@@ -298,8 +298,6 @@ static bool rxrpc_end_tx_phase(struct rxrpc_call *call, bool reply_begun,

	write_unlock(&call->state_lock);
	if (call->state == RXRPC_CALL_CLIENT_AWAIT_REPLY) {
		rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, 0, false, true,
				  rxrpc_propose_ack_client_tx_end);
		trace_rxrpc_transmit(call, rxrpc_transmit_await_reply);
	} else {
		trace_rxrpc_transmit(call, rxrpc_transmit_end);
Loading