mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 01:53:29 +02:00
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 <donald.robson@imgtec.com> Signed-off-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20231208163019.95913-1-donald.robson@imgtec.com
This commit is contained in:
parent
b39610c773
commit
f1f55ed3ff
|
|
@ -458,7 +458,7 @@ pvr_hwrt_dataset_create(struct pvr_file *pvr_file,
|
|||
struct drm_pvr_ioctl_create_hwrt_dataset_args *args)
|
||||
{
|
||||
struct pvr_hwrt_dataset *hwrt;
|
||||
int err;
|
||||
int err, i = 0;
|
||||
|
||||
/* Create and fill out the kernel structure */
|
||||
hwrt = kzalloc(sizeof(*hwrt), GFP_KERNEL);
|
||||
|
|
@ -466,35 +466,36 @@ pvr_hwrt_dataset_create(struct pvr_file *pvr_file,
|
|||
if (!hwrt)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
kref_init(&hwrt->ref_count);
|
||||
|
||||
err = hwrt_init_kernel_structure(pvr_file, args, hwrt);
|
||||
if (err < 0)
|
||||
goto err_free;
|
||||
|
||||
err = hwrt_init_common_fw_structure(pvr_file, args, hwrt);
|
||||
if (err < 0)
|
||||
goto err_free;
|
||||
goto err_fini_kernel_structure;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(hwrt->data); i++) {
|
||||
for (; i < ARRAY_SIZE(hwrt->data); i++) {
|
||||
err = hwrt_data_init_fw_structure(pvr_file, hwrt, args,
|
||||
&args->rt_data_args[i],
|
||||
&hwrt->data[i]);
|
||||
if (err < 0) {
|
||||
i--;
|
||||
/* Destroy already created structures. */
|
||||
for (; i >= 0; i--)
|
||||
hwrt_data_fini_fw_structure(hwrt, i);
|
||||
goto err_free;
|
||||
}
|
||||
if (err < 0)
|
||||
goto err_fini_data_structures;
|
||||
|
||||
hwrt->data[i].hwrt_dataset = hwrt;
|
||||
}
|
||||
|
||||
kref_init(&hwrt->ref_count);
|
||||
return hwrt;
|
||||
|
||||
err_fini_data_structures:
|
||||
while (--i >= 0)
|
||||
hwrt_data_fini_fw_structure(hwrt, i);
|
||||
|
||||
err_fini_kernel_structure:
|
||||
hwrt_fini_kernel_structure(hwrt);
|
||||
|
||||
err_free:
|
||||
pvr_hwrt_dataset_put(hwrt);
|
||||
kfree(hwrt);
|
||||
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user