瀏覽代碼

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 <dhowells@redhat.com>
David Howells 9 年之前
父節點
當前提交
ccbd3dbe85
共有 1 個文件被更改,包括 15 次插入11 次删除
  1. 15 11
      net/rxrpc/conn_event.c

+ 15 - 11
net/rxrpc/conn_event.c

@@ -149,19 +149,23 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn, int state,
 		call = rcu_dereference_protected(
 			conn->channels[i].call,
 			lockdep_is_held(&conn->channel_lock));
-		write_lock_bh(&call->state_lock);
-		if (call->state <= RXRPC_CALL_COMPLETE) {
-			call->state = state;
-			if (state == RXRPC_CALL_LOCALLY_ABORTED) {
-				call->local_abort = conn->local_abort;
-				set_bit(RXRPC_CALL_EV_CONN_ABORT, &call->events);
-			} else {
-				call->remote_abort = conn->remote_abort;
-				set_bit(RXRPC_CALL_EV_RCVD_ABORT, &call->events);
+		if (call) {
+			write_lock_bh(&call->state_lock);
+			if (call->state <= RXRPC_CALL_COMPLETE) {
+				call->state = state;
+				if (state == RXRPC_CALL_LOCALLY_ABORTED) {
+					call->local_abort = conn->local_abort;
+					set_bit(RXRPC_CALL_EV_CONN_ABORT,
+						&call->events);
+				} else {
+					call->remote_abort = conn->remote_abort;
+					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);