File drbd-fix-protocol-compatibility-with-drbd-8.4-state.patch of Package drbd.20953

From 30c947cfe2ae45bc084f29f200b4089faf5be35f Mon Sep 17 00:00:00 2001
From: Philipp Reisner <philipp.reisner@linbit.com>
Date: Wed, 16 Jun 2021 15:06:17 +0200
Subject: [PATCH] drbd: fix protocol compatibility with drbd-8.4 state changes

Commit e595bfc6 'drbd: Serialize connects and promotes properly' broke compatibility
with state changes in 8.4. The call chain is in that case:

receive_req_state()
  change_connection_state(..., NULL,)
    reply->is_disconnect; /* CRASH sind reply == NULL */

This went undetected so far, because receive_req_state() is part of the drbd-8.4
compability. In drbd-9.0 this is all replaced by the two-phase-commit protocol.

The fix is obvious, do not deref a NULL pointer.

NOTE: This change should _not_ be forward-ported to drbd-9.1
---
 drbd/drbd_receiver.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drbd/drbd_receiver.c b/drbd/drbd_receiver.c
index 21fb6067..f399a3c7 100644
--- a/drbd/drbd_receiver.c
+++ b/drbd/drbd_receiver.c
@@ -6044,13 +6044,21 @@ change_connection_state(struct drbd_connection *connection,
 {
 	struct drbd_resource *resource = connection->resource;
 	long t = resource->res_opts.auto_promote_timeout * HZ / 10;
-	bool is_disconnect = reply->is_disconnect;
-	bool is_connect = reply->is_connect;
+	bool is_disconnect = false;
+	bool is_connect = false;
 	struct drbd_peer_device *peer_device;
 	unsigned long irq_flags;
 	enum drbd_state_rv rv;
 	int vnr;
 
+	if (reply) {
+		is_disconnect = reply->is_disconnect;
+		is_connect = reply->is_connect;
+	} else if (mask.conn == conn_MASK) {
+		is_connect = val.conn == C_CONNECTED;
+		is_disconnect = val.conn == C_DISCONNECTING;
+	}
+
 	mask = convert_state(mask);
 	val = convert_state(val);
 
-- 
2.16.4

openSUSE Build Service is sponsored by