Skip to contentSkip to conversation

Patch "drm/mst: Avoid processing partially received up/down message transactions" has been added to the 3.18-stable tree

PATCH [email protected] 1 participant 1 message Jul 25, 2017

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

drm/mst: Avoid processing partially received up/down message transactions

to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
drm-mst-avoid-processing-partially-received-up-down-message-transactions.patch
and it can be found in the queue-3.18 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 636c4c3e762b62aa93632c645ca65879285b16e3 Mon Sep 17 00:00:00 2001

From: Imre Deak <[email protected]>
Date: Wed, 19 Jul 2017 16:46:32 +0300
Subject: drm/mst: Avoid processing partially received up/down message transactions

From: Imre Deak <[email protected]>

commit 636c4c3e762b62aa93632c645ca65879285b16e3 upstream.

Currently we may process up/down message transactions containing uninitialized data. This can happen if there was an error during the reception of any message in the transaction, but we happened to receive the last message correctly with the end-of-message flag set.

To avoid this abort the reception of the transaction when the first error is detected, rejecting any messages until a message with the start-of-message flag is received (which will start a new transaction). This is also what the DP 1.4 spec 2.11.8.2 calls for in this case.

In addtion this also prevents receiving bogus transactions without the first message with the the start-of-message flag set.

v2:
- unchanged
v3:
- git add the part that actually skips messages after an error in drm_dp_sideband_msg_build()

---
 drivers/gpu/drm/drm_dp_mst_topology.c |   31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)
drivers/gpu/drm/drm_dp_mst_topology.c +24 -7
@@ -330,6 +330,13 @@ static bool drm_dp_sideband_msg_build(st
 			return false;
 		}
 
+		/*
+		 * ignore out-of-order messages or messages that are part of a
+		 * failed transaction
+		 */
+		if (!recv_hdr.somt && !msg->have_somt)
+			return false;
+
 		/* get length contained in this portion */
 		msg->curchunk_len = recv_hdr.msg_len;
 		msg->curchunk_hdrlen = hdrlen;
@@ -2049,7 +2056,7 @@ out_unlock:
 }
 EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume);
 
-static void drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
+static bool drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
 {
 	int len;
 	u8 replyblock[32];
@@ -2064,12 +2071,12 @@ static void drm_dp_get_one_sb_msg(struct
 			       replyblock, len);
 	if (ret != len) {
 		DRM_DEBUG_KMS("failed to read DPCD down rep %d %d\n", len, ret);
-		return;
+		return false;
 	}
 	ret = drm_dp_sideband_msg_build(msg, replyblock, len, true);
 	if (!ret) {
 		DRM_DEBUG_KMS("sideband msg build failed %d\n", replyblock[0]);
-		return;
+		return false;
 	}
 	replylen = msg->curchunk_len + msg->curchunk_hdrlen;
 
@@ -2083,25 +2090,30 @@ static void drm_dp_get_one_sb_msg(struct
 		if (ret != len) {
 			DRM_DEBUG_KMS("failed to read a chunk (len %d, ret %d)\n",
 				      len, ret);
-			return;
+			return false;
 		}
 
 		ret = drm_dp_sideband_msg_build(msg, replyblock, len, false);
 		if (!ret) {
 			DRM_DEBUG_KMS("failed to build sideband msg\n");
-			return;
+			return false;
 		}
 
 		curreply += len;
 		replylen -= len;
 	}
+	return true;
 }
 
 static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
 {
 	int ret = 0;
 
-	drm_dp_get_one_sb_msg(mgr, false);
+	if (!drm_dp_get_one_sb_msg(mgr, false)) {
+		memset(&mgr->down_rep_recv, 0,
+		       sizeof(struct drm_dp_sideband_msg_rx));
+		return 0;
+	}
 
 	if (mgr->down_rep_recv.have_eomt) {
 		struct drm_dp_sideband_msg_tx *txmsg;
@@ -2157,7 +2169,12 @@ static int drm_dp_mst_handle_down_rep(st
 static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
 {
 	int ret = 0;
-	drm_dp_get_one_sb_msg(mgr, true);
+
+	if (!drm_dp_get_one_sb_msg(mgr, true)) {
+		memset(&mgr->up_req_recv, 0,
+		       sizeof(struct drm_dp_sideband_msg_rx));
+		return 0;
+	}
 
 	if (mgr->up_req_recv.have_eomt) {
 		struct drm_dp_sideband_msg_req_body msg;

Patches currently in stable-queue which might be from [email protected] are

queue-3.18/drm-mst-avoid-dereferencing-a-null-mstb-in-drm_dp_mst_handle_up_req.patch queue-3.18/drm-mst-avoid-processing-partially-received-up-down-message-transactions.patch queue-3.18/drm-mst-fix-error-handling-during-mst-sideband-message-reception.patch