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