소스 검색

disp: msm: dp: clear MST sim context during DP sim disable

After freeing MST sim context memory the pointer isn't set
to NULL leading to unauthorized memory access. Along with
this fix, this change also defers checking sim device ports
pointer at a more appropriate place in the function call.

Change-Id: I20c09edbd454c9d491060815dc73bae34aab6b08
Signed-off-by: Sandeep Gangadharaiah <[email protected]>
Sandeep Gangadharaiah 2 년 전
부모
커밋
31ae12f079
3개의 변경된 파일35개의 추가작업 그리고 33개의 파일을 삭제
  1. 8 9
      msm/dp/dp_debug.c
  2. 2 6
      msm/dp/dp_mst_sim.c
  3. 25 18
      msm/dp/dp_mst_sim_helper.c

+ 8 - 9
msm/dp/dp_debug.c

@@ -74,19 +74,18 @@ static int dp_debug_attach_sim_bridge(struct dp_debug_private *debug)
 {
 	int ret;
 
-	if (debug->sim_bridge)
-		return 0;
+	if (!debug->sim_bridge) {
+		ret = dp_sim_create_bridge(debug->dev, &debug->sim_bridge);
+		if (ret)
+			return ret;
 
-	ret = dp_sim_create_bridge(debug->dev, &debug->sim_bridge);
-	if (ret)
-		return ret;
+		if (debug->sim_bridge->register_hpd)
+			debug->sim_bridge->register_hpd(debug->sim_bridge,
+					dp_debug_sim_hpd_cb, debug);
+	}
 
 	dp_sim_update_port_num(debug->sim_bridge, 1);
 
-	if (debug->sim_bridge->register_hpd)
-		debug->sim_bridge->register_hpd(debug->sim_bridge,
-				dp_debug_sim_hpd_cb, debug);
-
 	return 0;
 }
 

+ 2 - 6
msm/dp/dp_mst_sim.c

@@ -342,10 +342,7 @@ int dp_sim_update_port_num(struct dp_aux_bridge *bridge, u32 port_num)
 		return -EINVAL;
 
 	sim_dev = to_dp_sim_dev(bridge);
-	DP_INFO("Update port count from %d to %d\n", port_num, sim_dev->port_num);
-
-	if (sim_dev->port_num > port_num && sim_dev->ports)
-		sim_dev->port_num = port_num;
+	DP_INFO("Update port count from %d to %d\n", sim_dev->port_num, port_num);
 
 	if (port_num > sim_dev->port_num) {
 		ports = devm_kzalloc(sim_dev->dev,
@@ -365,10 +362,9 @@ int dp_sim_update_port_num(struct dp_aux_bridge *bridge, u32 port_num)
 			memcpy(&ports[i], &output_port, sizeof(*ports));
 			ports[i].peer_guid[0] = i;
 		}
-
-		sim_dev->port_num = port_num;
 	}
 
+	sim_dev->port_num = port_num;
 	rc = dp_mst_sim_update(sim_dev->bridge.mst_ctx,
 			port_num, sim_dev->ports);
 	if (rc)

+ 25 - 18
msm/dp/dp_mst_sim_helper.c

@@ -1055,6 +1055,18 @@ static void dp_mst_sim_notify(struct dp_mst_sim_context *ctx,
 	queue_work(ctx->wq, &work->base);
 }
 
+static void dp_mst_sim_free_ports(struct dp_mst_sim_context *ctx)
+{
+	u32 i;
+
+	for (i = 0; i < ctx->port_num; i++)
+		kfree(ctx->ports[i].edid);
+
+	kfree(ctx->ports);
+	ctx->ports = NULL;
+	ctx->port_num = 0;
+}
+
 int dp_mst_sim_update(void *mst_sim_context, u32 port_num,
 		struct dp_mst_sim_port *ports)
 {
@@ -1064,7 +1076,7 @@ int dp_mst_sim_update(void *mst_sim_context, u32 port_num,
 	u32 update_mask = 0;
 	u32 i;
 
-	if (!ctx || port_num >= 15)
+	if (!ctx || port_num >= 15 || !ports)
 		return -EINVAL;
 
 	mutex_lock(&ctx->session_lock);
@@ -1081,19 +1093,17 @@ int dp_mst_sim_update(void *mst_sim_context, u32 port_num,
 		}
 	}
 
-	for (i = 0; i < ctx->port_num; i++)
-		kfree(ctx->ports[i].edid);
-	kfree(ctx->ports);
-	ctx->port_num = 0;
+	dp_mst_sim_free_ports(ctx);
 
-	if (port_num) {
-		ctx->ports = kcalloc(port_num, sizeof(*ports), GFP_KERNEL);
-		if (!ctx->ports) {
-			rc = -ENOMEM;
-			goto fail;
-		}
-		ctx->port_num = port_num;
+	if (!port_num)
+		goto end;
+
+	ctx->ports = kcalloc(port_num, sizeof(*ports), GFP_KERNEL);
+	if (!ctx->ports) {
+		rc = -ENOMEM;
+		goto fail;
 	}
+	ctx->port_num = port_num;
 
 	for (i = 0; i < port_num; i++) {
 		ctx->ports[i] = ports[i];
@@ -1116,13 +1126,10 @@ int dp_mst_sim_update(void *mst_sim_context, u32 port_num,
 	}
 
 fail:
-	if (rc) {
-		for (i = 0; i < ctx->port_num; i++)
-			kfree(ctx->ports[i].edid);
-		kfree(ctx->ports);
-		ctx->port_num = 0;
-	}
+	if (rc)
+		dp_mst_sim_free_ports(ctx);
 
+end:
 	mutex_unlock(&ctx->session_lock);
 
 	if (update_mask)