Commit 9ea79e99 authored by Philip Yang's avatar Philip Yang Committed by Jinjiang Tu
Browse files

drm/amdkfd: amdkfd_free_gtt_mem clear the correct pointer

mainline inclusion
from mainline-v6.12-rc1
commit c86ad39140bbcb9dc75a10046c2221f657e8083b
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAYRB0
CVE: CVE-2024-49991

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c86ad39140bbcb9dc75a10046c2221f657e8083b



--------------------------------

Pass pointer reference to amdgpu_bo_unref to clear the correct pointer,
otherwise amdgpu_bo_unref clear the local variable, the original pointer
not set to NULL, this could cause use-after-free bug.

Signed-off-by: default avatarPhilip Yang <Philip.Yang@amd.com>
Reviewed-by: default avatarFelix Kuehling <felix.kuehling@amd.com>
Acked-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>

Conflicts:
	drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
	drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
	drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
	drivers/gpu/drm/amd/amdkfd/kfd_device.c
	drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
	drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
	drivers/gpu/drm/amd/amdkfd/kfd_process.c
	drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
	drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
[conflicts due to 5b87245f ("drm/amdkfd: Simplify kfd2kgd interface")
isn't merged, and several calls aren't introduced.]
Signed-off-by: default avatarJinjiang Tu <tujinjiang@huawei.com>
parent fc269dcb
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -342,15 +342,15 @@ int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
	return r;
}

void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj)
void free_gtt_mem(struct kgd_dev *kgd, void **mem_obj)
{
	struct amdgpu_bo *bo = (struct amdgpu_bo *) mem_obj;
	struct amdgpu_bo **bo = (struct amdgpu_bo **) mem_obj;

	amdgpu_bo_reserve(bo, true);
	amdgpu_bo_kunmap(bo);
	amdgpu_bo_unpin(bo);
	amdgpu_bo_unreserve(bo);
	amdgpu_bo_unref(&(bo));
	amdgpu_bo_reserve(*bo, true);
	amdgpu_bo_kunmap(*bo);
	amdgpu_bo_unpin(*bo);
	amdgpu_bo_unreserve(*bo);
	amdgpu_bo_unref(bo);
}

void get_local_mem_info(struct kgd_dev *kgd,
+1 −1
Original line number Diff line number Diff line
@@ -137,7 +137,7 @@ void amdgpu_amdkfd_gpu_reset(struct kgd_dev *kgd);
int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
			void **mem_obj, uint64_t *gpu_addr,
			void **cpu_ptr, bool mqd_gfx9);
void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj);
void free_gtt_mem(struct kgd_dev *kgd, void **mem_obj);
void get_local_mem_info(struct kgd_dev *kgd,
			struct kfd_local_mem_info *mem_info);
uint64_t get_gpu_clock_counter(struct kgd_dev *kgd);
+2 −2
Original line number Diff line number Diff line
@@ -533,7 +533,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
kfd_doorbell_error:
	kfd_gtt_sa_fini(kfd);
kfd_gtt_sa_init_error:
	kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
	kfd->kfd2kgd->free_gtt_mem(kfd->kgd, &kfd->gtt_mem);
	dev_err(kfd_device,
		"device %x:%x NOT added due to errors\n",
		kfd->pdev->vendor, kfd->pdev->device);
@@ -550,7 +550,7 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd)
		kfd_topology_remove_device(kfd);
		kfd_doorbell_fini(kfd);
		kfd_gtt_sa_fini(kfd);
		kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
		kfd->kfd2kgd->free_gtt_mem(kfd->kgd, &kfd->gtt_mem);
	}

	kfree(kfd);
+1 −1
Original line number Diff line number Diff line
@@ -253,7 +253,7 @@ static void uninit_mqd(struct mqd_manager *mm, void *mqd,
	struct kfd_dev *kfd = mm->dev;

	if (mqd_mem_obj->gtt_mem) {
		kfd->kfd2kgd->free_gtt_mem(kfd->kgd, mqd_mem_obj->gtt_mem);
		kfd->kfd2kgd->free_gtt_mem(kfd->kgd, &mqd_mem_obj->gtt_mem);
		kfree(mqd_mem_obj);
	} else {
		kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
+1 −1
Original line number Diff line number Diff line
@@ -294,7 +294,7 @@ struct kfd2kgd_calls {
					void **mem_obj, uint64_t *gpu_addr,
					void **cpu_ptr, bool mqd_gfx9);

	void (*free_gtt_mem)(struct kgd_dev *kgd, void *mem_obj);
	void (*free_gtt_mem)(struct kgd_dev *kgd, void **mem_obj);

	void (*get_local_mem_info)(struct kgd_dev *kgd,
			struct kfd_local_mem_info *mem_info);