drm/nouveau/gsp: fix potential leak of memory used during acpi init
authorBen Skeggs <bskeggs@nvidia.com>
Tue, 17 Jun 2025 04:00:36 +0000 (14:00 +1000)
committerDanilo Krummrich <dakr@kernel.org>
Mon, 7 Jul 2025 14:32:44 +0000 (16:32 +0200)
If any of the ACPI calls fail, memory allocated for the input buffer
would be leaked.  Fix failure paths to free allocated memory.

Also add checks to ensure the allocations succeeded in the first place.

Reported-by: Danilo Krummrich <dakr@kernel.org>
Fixes: 176fdcbddfd2 ("drm/nouveau/gsp/r535: add support for booting GSP-RM")
Signed-off-by: Ben Skeggs <bskeggs@nvidia.com>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20250617040036.2932-1-bskeggs@nvidia.com
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c

index 23f80e16770582febcaddbb8c7d54ad26a974c09..588cb4ab85cb49c47784e65f80a98ea31ea91eb2 100644 (file)
@@ -719,7 +719,6 @@ r535_gsp_acpi_caps(acpi_handle handle, CAPS_METHOD_DATA *caps)
        union acpi_object argv4 = {
                .buffer.type    = ACPI_TYPE_BUFFER,
                .buffer.length  = 4,
-               .buffer.pointer = kmalloc(argv4.buffer.length, GFP_KERNEL),
        }, *obj;
 
        caps->status = 0xffff;
@@ -727,17 +726,22 @@ r535_gsp_acpi_caps(acpi_handle handle, CAPS_METHOD_DATA *caps)
        if (!acpi_check_dsm(handle, &NVOP_DSM_GUID, NVOP_DSM_REV, BIT_ULL(0x1a)))
                return;
 
+       argv4.buffer.pointer = kmalloc(argv4.buffer.length, GFP_KERNEL);
+       if (!argv4.buffer.pointer)
+               return;
+
        obj = acpi_evaluate_dsm(handle, &NVOP_DSM_GUID, NVOP_DSM_REV, 0x1a, &argv4);
        if (!obj)
-               return;
+               goto done;
 
        if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) ||
            WARN_ON(obj->buffer.length != 4))
-               return;
+               goto done;
 
        caps->status = 0;
        caps->optimusCaps = *(u32 *)obj->buffer.pointer;
 
+done:
        ACPI_FREE(obj);
 
        kfree(argv4.buffer.pointer);
@@ -754,24 +758,28 @@ r535_gsp_acpi_jt(acpi_handle handle, JT_METHOD_DATA *jt)
        union acpi_object argv4 = {
                .buffer.type    = ACPI_TYPE_BUFFER,
                .buffer.length  = sizeof(caps),
-               .buffer.pointer = kmalloc(argv4.buffer.length, GFP_KERNEL),
        }, *obj;
 
        jt->status = 0xffff;
 
+       argv4.buffer.pointer = kmalloc(argv4.buffer.length, GFP_KERNEL);
+       if (!argv4.buffer.pointer)
+               return;
+
        obj = acpi_evaluate_dsm(handle, &JT_DSM_GUID, JT_DSM_REV, 0x1, &argv4);
        if (!obj)
-               return;
+               goto done;
 
        if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) ||
            WARN_ON(obj->buffer.length != 4))
-               return;
+               goto done;
 
        jt->status = 0;
        jt->jtCaps = *(u32 *)obj->buffer.pointer;
        jt->jtRevId = (jt->jtCaps & 0xfff00000) >> 20;
        jt->bSBIOSCaps = 0;
 
+done:
        ACPI_FREE(obj);
 
        kfree(argv4.buffer.pointer);