Commit 7d50b92d authored by Dan Carpenter's avatar Dan Carpenter Committed by Alex Deucher

drm/amdkfd: potential crash in kfd_create_indirect_link_prop()

This code has two bugs.  If kfd_topology_device_by_proximity_domain()
failed on the first iteration through the loop then "cpu_link" is
uninitialized and should not be dereferenced.

The second bug is that we cannot dereference a list iterator when it
points to the list head.  In other words, if we exit the
list_for_each_entry() loop exits without hitting a break then "cpu_link"
is not a valid pointer and should not be dereferenced.

Fix both of these problems by setting "cpu_link" to NULL when it is invalid
and non-NULL when it is valid.  That makes it easier to test for
valid vs invalid.

Fixes: 0f28cca8 ("drm/amdkfd: Extend KFD device topology to surface peer-to-peer links")
Signed-off-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent e48e6a13
...@@ -1392,8 +1392,8 @@ static int kfd_build_p2p_node_entry(struct kfd_topology_device *dev, ...@@ -1392,8 +1392,8 @@ static int kfd_build_p2p_node_entry(struct kfd_topology_device *dev,
static int kfd_create_indirect_link_prop(struct kfd_topology_device *kdev, int gpu_node) static int kfd_create_indirect_link_prop(struct kfd_topology_device *kdev, int gpu_node)
{ {
struct kfd_iolink_properties *gpu_link, *tmp_link, *cpu_link;
struct kfd_iolink_properties *props = NULL, *props2 = NULL; struct kfd_iolink_properties *props = NULL, *props2 = NULL;
struct kfd_iolink_properties *gpu_link, *cpu_link;
struct kfd_topology_device *cpu_dev; struct kfd_topology_device *cpu_dev;
int ret = 0; int ret = 0;
int i, num_cpu; int i, num_cpu;
...@@ -1416,16 +1416,19 @@ static int kfd_create_indirect_link_prop(struct kfd_topology_device *kdev, int g ...@@ -1416,16 +1416,19 @@ static int kfd_create_indirect_link_prop(struct kfd_topology_device *kdev, int g
continue; continue;
/* find CPU <--> CPU links */ /* find CPU <--> CPU links */
cpu_link = NULL;
cpu_dev = kfd_topology_device_by_proximity_domain(i); cpu_dev = kfd_topology_device_by_proximity_domain(i);
if (cpu_dev) { if (cpu_dev) {
list_for_each_entry(cpu_link, list_for_each_entry(tmp_link,
&cpu_dev->io_link_props, list) { &cpu_dev->io_link_props, list) {
if (cpu_link->node_to == gpu_link->node_to) if (tmp_link->node_to == gpu_link->node_to) {
cpu_link = tmp_link;
break; break;
}
} }
} }
if (cpu_link->node_to != gpu_link->node_to) if (!cpu_link)
return -ENOMEM; return -ENOMEM;
/* CPU <--> CPU <--> GPU, GPU node*/ /* CPU <--> CPU <--> GPU, GPU node*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment