[prev in list] [next in list] [prev in thread] [next in thread] 

List:       git-commits-head
Subject:    drm/dp/mst: Get validated port ref in drm_dp_update_payload_part1()
From:       "Linux Kernel Mailing List" <linux-kernel () vger ! kernel ! org>
Date:       2016-04-30 0:48:59
Message-ID: 20160430004859.5ACE2660F69 () gitolite ! kernel ! org
[Download RAW message or body]

Web:        https://git.kernel.org/torvalds/c/263efde31f97c498e1ebad30e4d2906609d7ad6b
                
Commit:     263efde31f97c498e1ebad30e4d2906609d7ad6b
Parent:     bd0b560a75bcebdcb48d82ed81f6b77c12771107
Refname:    refs/heads/master
Author:     cpaul@redhat.com <cpaul@redhat.com>
AuthorDate: Fri Apr 22 16:08:46 2016 -0400
Committer:  Dave Airlie <airlied@redhat.com>
CommitDate: Wed Apr 27 09:26:12 2016 +1000

    drm/dp/mst: Get validated port ref in drm_dp_update_payload_part1()
    
    We can thank KASAN for finding this, otherwise I probably would have spent
    hours on it. This fixes a somewhat harder to trigger kernel panic, occuring
    while enabling MST where the port we were currently updating the payload on
    would have all of it's refs dropped before we finished what we were doing:
    
    ==================================================================
    BUG: KASAN: use-after-free in drm_dp_update_payload_part1+0xb3f/0xdb0 \
[drm_kms_helper] at addr ffff8800d29de018  Read of size 4 by task Xorg/973
    =============================================================================
    BUG kmalloc-2048 (Tainted: G    B   W      ): kasan: bad access detected
    -----------------------------------------------------------------------------
    
    INFO: Allocated in drm_dp_add_port+0x1aa/0x1ed0 [drm_kms_helper] age=16477 cpu=0 \
pid=2175  ___slab_alloc+0x472/0x490
    	__slab_alloc+0x20/0x40
    	kmem_cache_alloc_trace+0x151/0x190
    	drm_dp_add_port+0x1aa/0x1ed0 [drm_kms_helper]
    	drm_dp_send_link_address+0x526/0x960 [drm_kms_helper]
    	drm_dp_check_and_send_link_address+0x1ac/0x210 [drm_kms_helper]
    	drm_dp_mst_link_probe_work+0x77/0xd0 [drm_kms_helper]
    	process_one_work+0x562/0x1350
    	worker_thread+0xd9/0x1390
    	kthread+0x1c5/0x260
    	ret_from_fork+0x22/0x40
    INFO: Freed in drm_dp_free_mst_port+0x50/0x60 [drm_kms_helper] age=7521 cpu=0 \
pid=2175  __slab_free+0x17f/0x2d0
    	kfree+0x169/0x180
    	drm_dp_free_mst_port+0x50/0x60 [drm_kms_helper]
    	drm_dp_destroy_connector_work+0x2b8/0x490 [drm_kms_helper]
    	process_one_work+0x562/0x1350
    	worker_thread+0xd9/0x1390
    	kthread+0x1c5/0x260
    	ret_from_fork+0x22/0x40
    
    which on this T460s, would eventually lead to kernel panics in somewhat
    random places later in intel_mst_enable_dp() if we got lucky enough.
    
    Signed-off-by: Lyude <cpaul@redhat.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: Dave Airlie <airlied@redhat.com>
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c \
b/drivers/gpu/drm/drm_dp_mst_topology.c index e17fbda..935d8cc 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -1796,6 +1796,11 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr \
*mgr)  req_payload.start_slot = cur_slots;
 		if (mgr->proposed_vcpis[i]) {
 			port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi);
+			port = drm_dp_get_validated_port_ref(mgr, port);
+			if (!port) {
+				mutex_unlock(&mgr->payload_lock);
+				return -EINVAL;
+			}
 			req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots;
 			req_payload.vcpi = mgr->proposed_vcpis[i]->vcpi;
 		} else {
@@ -1823,6 +1828,9 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr \
*mgr)  mgr->payloads[i].payload_state = req_payload.payload_state;
 		}
 		cur_slots += req_payload.num_slots;
+
+		if (port)
+			drm_dp_put_port(port);
 	}
 
 	for (i = 0; i < mgr->max_payloads; i++) {
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic