Skip to content

Commit f1f55ed

Browse files
drobson-imgtecmripard
authored andcommitted
drm/imagination: Fixed oops when misusing ioctl CREATE_HWRT_DATASET
While writing the matching IGT suite I discovered that it's possible to cause a kernel oops when using DRM_IOCTL_PVR_CREATE_HWRT_DATASET when the call to hwrt_init_common_fw_structure() fails. Use an unwind-type error path to avoid cleaning up the object using the the release function before it is fully resolved. Signed-off-by: Donald Robson <[email protected]> Signed-off-by: Maxime Ripard <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent b39610c commit f1f55ed

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

drivers/gpu/drm/imagination/pvr_hwrt.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -458,43 +458,44 @@ pvr_hwrt_dataset_create(struct pvr_file *pvr_file,
458458
struct drm_pvr_ioctl_create_hwrt_dataset_args *args)
459459
{
460460
struct pvr_hwrt_dataset *hwrt;
461-
int err;
461+
int err, i = 0;
462462

463463
/* Create and fill out the kernel structure */
464464
hwrt = kzalloc(sizeof(*hwrt), GFP_KERNEL);
465465

466466
if (!hwrt)
467467
return ERR_PTR(-ENOMEM);
468468

469-
kref_init(&hwrt->ref_count);
470-
471469
err = hwrt_init_kernel_structure(pvr_file, args, hwrt);
472470
if (err < 0)
473471
goto err_free;
474472

475473
err = hwrt_init_common_fw_structure(pvr_file, args, hwrt);
476474
if (err < 0)
477-
goto err_free;
475+
goto err_fini_kernel_structure;
478476

479-
for (int i = 0; i < ARRAY_SIZE(hwrt->data); i++) {
477+
for (; i < ARRAY_SIZE(hwrt->data); i++) {
480478
err = hwrt_data_init_fw_structure(pvr_file, hwrt, args,
481479
&args->rt_data_args[i],
482480
&hwrt->data[i]);
483-
if (err < 0) {
484-
i--;
485-
/* Destroy already created structures. */
486-
for (; i >= 0; i--)
487-
hwrt_data_fini_fw_structure(hwrt, i);
488-
goto err_free;
489-
}
481+
if (err < 0)
482+
goto err_fini_data_structures;
490483

491484
hwrt->data[i].hwrt_dataset = hwrt;
492485
}
493486

487+
kref_init(&hwrt->ref_count);
494488
return hwrt;
495489

490+
err_fini_data_structures:
491+
while (--i >= 0)
492+
hwrt_data_fini_fw_structure(hwrt, i);
493+
494+
err_fini_kernel_structure:
495+
hwrt_fini_kernel_structure(hwrt);
496+
496497
err_free:
497-
pvr_hwrt_dataset_put(hwrt);
498+
kfree(hwrt);
498499

499500
return ERR_PTR(err);
500501
}

0 commit comments

Comments
 (0)