Commit ccbd3dbe authored by David Howells's avatar David Howells

rxrpc: Fix a potential NULL-pointer deref in rxrpc_abort_calls

The call pointer in a channel on a connection will be NULL if there's no
active call on that channel.  rxrpc_abort_calls() needs to check for this
before trying to take the call's state_lock.
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent 3201a39b
...@@ -149,20 +149,24 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn, int state, ...@@ -149,20 +149,24 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn, int state,
call = rcu_dereference_protected( call = rcu_dereference_protected(
conn->channels[i].call, conn->channels[i].call,
lockdep_is_held(&conn->channel_lock)); lockdep_is_held(&conn->channel_lock));
if (call) {
write_lock_bh(&call->state_lock); write_lock_bh(&call->state_lock);
if (call->state <= RXRPC_CALL_COMPLETE) { if (call->state <= RXRPC_CALL_COMPLETE) {
call->state = state; call->state = state;
if (state == RXRPC_CALL_LOCALLY_ABORTED) { if (state == RXRPC_CALL_LOCALLY_ABORTED) {
call->local_abort = conn->local_abort; call->local_abort = conn->local_abort;
set_bit(RXRPC_CALL_EV_CONN_ABORT, &call->events); set_bit(RXRPC_CALL_EV_CONN_ABORT,
&call->events);
} else { } else {
call->remote_abort = conn->remote_abort; call->remote_abort = conn->remote_abort;
set_bit(RXRPC_CALL_EV_RCVD_ABORT, &call->events); set_bit(RXRPC_CALL_EV_RCVD_ABORT,
&call->events);
} }
rxrpc_queue_call(call); rxrpc_queue_call(call);
} }
write_unlock_bh(&call->state_lock); write_unlock_bh(&call->state_lock);
} }
}
spin_unlock(&conn->channel_lock); spin_unlock(&conn->channel_lock);
_leave(""); _leave("");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment