Skip to content

Commit ccbd3db

Browse files
committed
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: David Howells <[email protected]>
1 parent 3201a39 commit ccbd3db

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

net/rxrpc/conn_event.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -149,19 +149,23 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn, int state,
149149
call = rcu_dereference_protected(
150150
conn->channels[i].call,
151151
lockdep_is_held(&conn->channel_lock));
152-
write_lock_bh(&call->state_lock);
153-
if (call->state <= RXRPC_CALL_COMPLETE) {
154-
call->state = state;
155-
if (state == RXRPC_CALL_LOCALLY_ABORTED) {
156-
call->local_abort = conn->local_abort;
157-
set_bit(RXRPC_CALL_EV_CONN_ABORT, &call->events);
158-
} else {
159-
call->remote_abort = conn->remote_abort;
160-
set_bit(RXRPC_CALL_EV_RCVD_ABORT, &call->events);
152+
if (call) {
153+
write_lock_bh(&call->state_lock);
154+
if (call->state <= RXRPC_CALL_COMPLETE) {
155+
call->state = state;
156+
if (state == RXRPC_CALL_LOCALLY_ABORTED) {
157+
call->local_abort = conn->local_abort;
158+
set_bit(RXRPC_CALL_EV_CONN_ABORT,
159+
&call->events);
160+
} else {
161+
call->remote_abort = conn->remote_abort;
162+
set_bit(RXRPC_CALL_EV_RCVD_ABORT,
163+
&call->events);
164+
}
165+
rxrpc_queue_call(call);
161166
}
162-
rxrpc_queue_call(call);
167+
write_unlock_bh(&call->state_lock);
163168
}
164-
write_unlock_bh(&call->state_lock);
165169
}
166170

167171
spin_unlock(&conn->channel_lock);

0 commit comments

Comments
 (0)