Skip to content

Commit 315fbed

Browse files
committed
plugin/amdgpu: fix resource leaks in drm dump error paths
Several error paths in amdgpu_plugin_drm_dump_file() leak resources. The drmPrimeHandleToFD() and open_img_file() failures use break instead of goto exit, which skips per-iteration cleanup and lets the function continue dumping metadata with a stale ret value. Replace break with proper resource cleanup and goto exit. The vm_info_entries buffer is not freed when the ioctl or allocate_vm_entries() calls fail after allocating it, and the buffer from posix_memalign() is never freed after sdma_copy_bo(), leaking memory on every loop iteration. Add the missing xfree() calls. Check the amdgpu_device_initialize() return value because h_dev is undefined on failure. Move list_handles_entries cleanup into the exit block because error paths that goto exit skip the existing xfree() call after the loop. Add a NULL check before free_e(rd) because rd allocation can fail before the struct is initialized. Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
1 parent b518e76 commit 315fbed

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

plugins/amdgpu/amdgpu_plugin_drm.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ int amdgpu_plugin_drm_dump_file(int fd, int id, struct stat *drm)
251251
size_t image_size;
252252
struct tp_node *tp_node;
253253
struct drm_amdgpu_gem_list_handles list_handles_args = { 0 };
254-
struct drm_amdgpu_gem_list_handles_entry *list_handles_entries;
254+
struct drm_amdgpu_gem_list_handles_entry *list_handles_entries = NULL;
255255
int num_bos;
256256

257257
rd = xmalloc(sizeof(*rd));
@@ -353,6 +353,7 @@ int amdgpu_plugin_drm_dump_file(int fd, int id, struct stat *drm)
353353
ret = drmIoctl(fd, DRM_IOCTL_AMDGPU_GEM_OP, &vm_info_args);
354354
if (ret) {
355355
pr_perror("Failed to call vm info ioctl");
356+
xfree(vm_info_entries);
356357
goto exit;
357358
}
358359

@@ -371,6 +372,7 @@ int amdgpu_plugin_drm_dump_file(int fd, int id, struct stat *drm)
371372
ret = drmIoctl(fd, DRM_IOCTL_AMDGPU_GEM_OP, &vm_info_args);
372373
if (ret) {
373374
pr_perror("Failed to call vm info ioctl");
375+
xfree(vm_info_entries);
374376
goto exit;
375377
}
376378
} else {
@@ -379,8 +381,10 @@ int amdgpu_plugin_drm_dump_file(int fd, int id, struct stat *drm)
379381

380382
boinfo->num_of_vms = num_vm_entries;
381383
ret = allocate_vm_entries(boinfo, num_vm_entries);
382-
if (ret)
384+
if (ret) {
385+
xfree(vm_info_entries);
383386
goto exit;
387+
}
384388

385389
for (int j = 0; j < num_vm_entries; j++) {
386390
DrmVmEntry *vminfo = boinfo->vm_entries[j];
@@ -393,20 +397,30 @@ int amdgpu_plugin_drm_dump_file(int fd, int id, struct stat *drm)
393397
}
394398

395399
ret = amdgpu_device_initialize(fd, &major, &minor, &h_dev);
400+
if (ret) {
401+
pr_perror("Failed to initialize amdgpu device");
402+
xfree(vm_info_entries);
403+
goto exit;
404+
}
396405

397406
device_fd = amdgpu_device_get_fd(h_dev);
398407

399408
ret = drmPrimeHandleToFD(device_fd, boinfo->handle, 0, &dmabuf_fd);
400409
if (ret) {
401410
pr_perror("Failed to get dmabuf fd from handle");
402-
break;
411+
amdgpu_device_deinitialize(h_dev);
412+
xfree(vm_info_entries);
413+
goto exit;
403414
}
404415

405416
snprintf(img_path, sizeof(img_path), IMG_DRM_PAGES_FILE, rd->id, rd->drm_render_minor, i);
406417
bo_contents_fp = open_img_file(img_path, true, &image_size, true);
407418
if (!bo_contents_fp) {
408419
ret = -errno;
409-
break;
420+
close(dmabuf_fd);
421+
amdgpu_device_deinitialize(h_dev);
422+
xfree(vm_info_entries);
423+
goto exit;
410424
}
411425

412426
ret = posix_memalign(&buffer, sysconf(_SC_PAGE_SIZE), handle_entry.size);
@@ -424,6 +438,8 @@ int amdgpu_plugin_drm_dump_file(int fd, int id, struct stat *drm)
424438
ret = sdma_copy_bo(dmabuf_fd, handle_entry.size, bo_contents_fp, buffer, handle_entry.size, h_dev, 0x1000,
425439
SDMA_OP_VRAM_READ, false);
426440

441+
xfree(buffer);
442+
427443
if (dmabuf_fd != KFD_INVALID_FD)
428444
close(dmabuf_fd);
429445

@@ -436,7 +452,6 @@ int amdgpu_plugin_drm_dump_file(int fd, int id, struct stat *drm)
436452

437453
xfree(vm_info_entries);
438454
}
439-
xfree(list_handles_entries);
440455

441456
for (int i = 0; i < num_bos; i++) {
442457
DrmBoEntry *boinfo = rd->bo_entries[i];
@@ -471,7 +486,9 @@ int amdgpu_plugin_drm_dump_file(int fd, int id, struct stat *drm)
471486

472487
xfree(buf);
473488
exit:
474-
free_e(rd);
489+
xfree(list_handles_entries);
490+
if (rd)
491+
free_e(rd);
475492
return ret;
476493
}
477494

0 commit comments

Comments
 (0)