Re: [PATCH] drm/amd/display: Fix use-after-free bugs in KUnit tests

John Harrison <[email protected]> Wed, 29 Jul 2026 14:43:59 -0700
Newsgroups org.freedesktop.lists.amd-gfx,org.freedesktop.lists.dri-devel
Message-ID <[email protected]>
On 7/29/26 14:40, Alex Hung wrote:
> On 7/29/26 15:24, John Harrison wrote:
>> On 7/24/26 14:36, Alex Hung wrote:
>>> On 7/24/26 15:09, John Harrison wrote:
>>>> On 7/24/26 12:37, Alex Hung wrote:
>>>>> Reviewed-by: Alex Hung <[email protected]>
>>>>>
>>>>> With two comments:
>>>>> 1. There is a minor conflicts on include
>>>>> 2. The following code seems to have the same patterns (passing to 
>>>>> drmm_* functions). Do they need to be changed too?
>>>> None of those functions exist in my tree. Which might also explain 
>>>> the include conflict. I'm using drm-tip fetched the same day I 
>>>> posted the patch. Should I be basing the patch on a different tree?
>>>
>>> My bad. My local branch contains additional patches.
>>>
>>> I will create a patch for this four additional changes. Thanks for 
>>> pointing this out.
>> Can this patch be merged? It would be good to get the existing issues 
>> fixed.
>
> Hi John,
>
> This patch is merged in Alex Deucher's amd-staging-drm-nex tree 
> (https://gitlab.freedesktop.org/agd5f/linux)
>
> The commit is 
> https://gitlab.freedesktop.org/agd5f/linux/-/commit/637871507797e15bb109cec428877e56cfd94266 
>
Okay, cool. I checked drm-tip and it wasn't there yet so figured it was 
worth a ping. Sorry for the noise.

Thanks,
John.


>
>>
>> Thanks,
>> John.
>>
>>>
>>>>
>>>> John.
>>>>
>>>>
>>>>>
>>>>>
>>>>> --- drivers/gpu/drm/amd/display/amdgpu_dm/tests/ 
>>>>> amdgpu_dm_connector_test.c
>>>>> +++ drivers/gpu/drm/amd/display/amdgpu_dm/tests/ 
>>>>> amdgpu_dm_connector_test.c
>>>>> @@ -3645,7 +3645,7 @@ static struct dm_test_stream_ctx 
>>>>> *dm_test_stream_ctx_alloc(struct kunit *test)
>>>>> DRIVER_MODESET);
>>>>>         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->drm);
>>>>>
>>>>> -       ctx->aconnector = kunit_kzalloc(test, sizeof(*ctx- 
>>>>> >aconnector), GFP_KERNEL);
>>>>> +       ctx->aconnector = drmm_kzalloc(ctx->drm, sizeof(*ctx- 
>>>>> >aconnector), GFP_KERNEL);
>>>>>         KUNIT_ASSERT_NOT_NULL(test, ctx->aconnector);
>>>>>         KUNIT_ASSERT_EQ(test,
>>>>>                 drmm_connector_init(ctx->drm, &ctx->aconnector->base,
>>>>> @@ -3903,7 +3903,7 @@ static void 
>>>>> dm_test_poll_dac_load_returns_cached(struct kunit *test)
>>>>>         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
>>>>>         adev = drm_to_adev(drm);
>>>>>
>>>>> -       aconnector = kunit_kzalloc(test, sizeof(*aconnector), 
>>>>> GFP_KERNEL);
>>>>> +       aconnector = drmm_kzalloc(drm, sizeof(*aconnector), 
>>>>> GFP_KERNEL);
>>>>>         KUNIT_ASSERT_NOT_NULL(test, aconnector);
>>>>>         KUNIT_ASSERT_EQ(test,
>>>>>                 drmm_connector_init(drm, &aconnector->base,
>>>>> @@ -3950,7 +3950,7 @@ static struct amdgpu_dm_connector 
>>>>> *dm_test_reg_connector(struct kunit *test)
>>>>> DRIVER_MODESET);
>>>>>         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
>>>>>
>>>>> -       aconnector = kunit_kzalloc(test, sizeof(*aconnector), 
>>>>> GFP_KERNEL);
>>>>> +       aconnector = drmm_kzalloc(drm, sizeof(*aconnector), 
>>>>> GFP_KERNEL);
>>>>>         KUNIT_ASSERT_NOT_NULL(test, aconnector);
>>>>>         KUNIT_ASSERT_EQ(test,
>>>>>                 drmm_connector_init(drm, &aconnector->base,
>>>>> @@ -4405,7 +4405,7 @@ dm_test_modes_ctx_alloc(struct kunit *test, 
>>>>> int connector_type)
>>>>>         ctx->drm = dm_test_alloc_drm(test);
>>>>>         ctx->aconnector = dm_test_add_connector(test, ctx->drm, 
>>>>> connector_type);
>>>>>
>>>>> -       ctx->aenc = kunit_kzalloc(test, sizeof(*ctx->aenc), 
>>>>> GFP_KERNEL);
>>>>> +       ctx->aenc = drmm_kzalloc(ctx->drm, sizeof(*ctx->aenc), 
>>>>> GFP_KERNEL);
>>>>>         KUNIT_ASSERT_NOT_NULL(test, ctx->aenc);
>>>>>         KUNIT_ASSERT_EQ(test,
>>>>>                         drmm_encoder_init(ctx->drm, &ctx->aenc- 
>>>>> >base, NULL,
>>>>>
>>>>>
>>>>> On 7/23/26 17:35, John Harrison wrote:
>>>>>> When running the KUnit tests with memory debugging enabled, a 
>>>>>> bunch of
>>>>>> use-after-free errors are hit. These are due to using KUnit managed
>>>>>> memory for the test objects but then giving them over to DRM managed
>>>>>> objects. The KUnit stuff is deallocated first and when the DRM side
>>>>>> calls its clean up helpers, it hits memory that has been freed 
>>>>>> already.
>>>>>>
>>>>>> NB: There is still a use-after-free bug in the writeback tests.
>>>>>> However, fixing that requires driver side changes as well as test 
>>>>>> side
>>>>>> changes. Those changes are part of:
>>>>>>    https://patchwork.freedesktop.org/series/152420/
>>>>>>
>>>>>> Signed-off-by: John Harrison <[email protected]>
>>>>>> CC: Alex Hung <[email protected]>
>>>>>> CC: Harry Wentland <[email protected]>
>>>>>> ---
>>>>>>   .../tests/amdgpu_dm_connector_test.c          | 37 +++++++++ 
>>>>>> +---------
>>>>>>   .../amdgpu_dm/tests/amdgpu_dm_kunit_helpers.c |  3 +-
>>>>>>   .../amdgpu_dm/tests/amdgpu_dm_wb_test.c       |  5 ++-
>>>>>>   3 files changed, 24 insertions(+), 21 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/ 
>>>>>> amdgpu_dm_connector_test.c 
>>>>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/ 
>>>>>> tests/amdgpu_dm_connector_test.c
>>>>>> index 0a5d439f66c3..93a854d4fdfa 100644
>>>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/ 
>>>>>> amdgpu_dm_connector_test.c
>>>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/ 
>>>>>> amdgpu_dm_connector_test.c
>>>>>> @@ -12,6 +12,7 @@
>>>>>>   #include <drm/drm_crtc.h>
>>>>>>   #include <drm/drm_edid.h>
>>>>>>   #include <drm/drm_kunit_helpers.h>
>>>>>> +#include <drm/drm_managed.h>
>>>>>>   #include <drm/drm_mode_object.h>
>>>>>>   #include <drm/drm_property.h>
>>>>>>   #include <linux/hdmi.h>
>>>>>> @@ -1449,7 +1450,7 @@ static void 
>>>>>> dm_test_funcs_reset_sets_defaults(struct kunit *test)
>>>>>>                              DRIVER_MODESET);
>>>>>>       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
>>>>>>   -    connector = kunit_kzalloc(test, sizeof(*connector), 
>>>>>> GFP_KERNEL);
>>>>>> +    connector = drmm_kzalloc(drm, sizeof(*connector), GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, connector);
>>>>>>         drmm_connector_init(drm, connector, 
>>>>>> &dm_test_connector_funcs,
>>>>>> @@ -1488,7 +1489,7 @@ static void 
>>>>>> dm_test_funcs_reset_edp_abm_level(struct kunit *test)
>>>>>>                              DRIVER_MODESET);
>>>>>>       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
>>>>>>   -    connector = kunit_kzalloc(test, sizeof(*connector), 
>>>>>> GFP_KERNEL);
>>>>>> +    connector = drmm_kzalloc(drm, sizeof(*connector), GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, connector);
>>>>>>         drmm_connector_init(drm, connector, 
>>>>>> &dm_test_connector_funcs,
>>>>>> @@ -1526,7 +1527,7 @@ static void 
>>>>>> dm_test_funcs_reset_edp_abm_disabled(struct kunit *test)
>>>>>>                              DRIVER_MODESET);
>>>>>>       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
>>>>>>   -    connector = kunit_kzalloc(test, sizeof(*connector), 
>>>>>> GFP_KERNEL);
>>>>>> +    connector = drmm_kzalloc(drm, sizeof(*connector), GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, connector);
>>>>>>         drmm_connector_init(drm, connector, 
>>>>>> &dm_test_connector_funcs,
>>>>>> @@ -1568,7 +1569,7 @@ static void 
>>>>>> dm_test_atomic_dup_state_copies_fields(struct kunit *test)
>>>>>>                              DRIVER_MODESET);
>>>>>>       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
>>>>>>   -    connector = kunit_kzalloc(test, sizeof(*connector), 
>>>>>> GFP_KERNEL);
>>>>>> +    connector = drmm_kzalloc(drm, sizeof(*connector), GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, connector);
>>>>>>         drmm_connector_init(drm, connector, 
>>>>>> &dm_test_connector_funcs,
>>>>>> @@ -2359,8 +2360,8 @@ static void setup_panel_type_fixture(struct 
>>>>>> kunit *test,
>>>>>>       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fixture->drm);
>>>>>>       fixture->adev = drm_to_adev(fixture->drm);
>>>>>>   -    fixture->aconnector = kunit_kzalloc(test, sizeof(*fixture- 
>>>>>> >aconnector),
>>>>>> -                        GFP_KERNEL);
>>>>>> +    fixture->aconnector = drmm_kzalloc(fixture->drm, 
>>>>>> sizeof(*fixture->aconnector),
>>>>>> +                       GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fixture->aconnector);
>>>>>>       fixture->link = kunit_kzalloc(test, sizeof(*fixture->link), 
>>>>>> GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fixture->link);
>>>>>> @@ -2554,9 +2555,9 @@ static void 
>>>>>> dm_test_update_subconnector_dp_with_sink(struct kunit *test)
>>>>>>                              DRIVER_MODESET);
>>>>>>       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
>>>>>>   -    aconnector = kunit_kzalloc(test, sizeof(*aconnector), 
>>>>>> GFP_KERNEL);
>>>>>> +    aconnector = drmm_kzalloc(drm, sizeof(*aconnector), 
>>>>>> GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, aconnector);
>>>>>> -    link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
>>>>>> +    link = drmm_kzalloc(drm, sizeof(*link), GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, link);
>>>>>>         drmm_connector_init(drm, &aconnector->base, 
>>>>>> &dm_test_connector_funcs,
>>>>>> @@ -2598,9 +2599,9 @@ static void 
>>>>>> dm_test_update_subconnector_dp_no_sink(struct kunit *test)
>>>>>>                              DRIVER_MODESET);
>>>>>>       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
>>>>>>   -    aconnector = kunit_kzalloc(test, sizeof(*aconnector), 
>>>>>> GFP_KERNEL);
>>>>>> +    aconnector = drmm_kzalloc(drm, sizeof(*aconnector), 
>>>>>> GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, aconnector);
>>>>>> -    link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
>>>>>> +    link = drmm_kzalloc(drm, sizeof(*link), GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, link);
>>>>>>         drmm_connector_init(drm, &aconnector->base, 
>>>>>> &dm_test_connector_funcs,
>>>>>> @@ -2641,9 +2642,9 @@ static void 
>>>>>> dm_test_update_subconnector_non_dp_noop(struct kunit *test)
>>>>>>                              DRIVER_MODESET);
>>>>>>       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
>>>>>>   -    aconnector = kunit_kzalloc(test, sizeof(*aconnector), 
>>>>>> GFP_KERNEL);
>>>>>> +    aconnector = drmm_kzalloc(drm, sizeof(*aconnector), 
>>>>>> GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, aconnector);
>>>>>> -    link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
>>>>>> +    link = drmm_kzalloc(drm, sizeof(*link), GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, link);
>>>>>>         drmm_connector_init(drm, &aconnector->base, 
>>>>>> &dm_test_connector_funcs,
>>>>>> @@ -2657,7 +2658,7 @@ static void 
>>>>>> dm_test_update_subconnector_non_dp_noop(struct kunit *test)
>>>>>>         link->dpcd_caps.dongle_type = 
>>>>>> DISPLAY_DONGLE_DP_HDMI_CONVERTER;
>>>>>>       aconnector->dc_link = link;
>>>>>> -    aconnector->dc_sink = kunit_kzalloc(test, 
>>>>>> sizeof(*aconnector- >dc_sink), GFP_KERNEL);
>>>>>> +    aconnector->dc_sink = drmm_kzalloc(drm, sizeof(*aconnector- 
>>>>>> >dc_sink), GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, aconnector->dc_sink);
>>>>>>         update_subconnector_property(aconnector);
>>>>>> @@ -2804,7 +2805,7 @@ static struct amdgpu_dm_connector 
>>>>>> *dm_test_add_connector(struct kunit *test,
>>>>>>   {
>>>>>>       struct amdgpu_dm_connector *aconnector;
>>>>>>   -    aconnector = kunit_kzalloc(test, sizeof(*aconnector), 
>>>>>> GFP_KERNEL);
>>>>>> +    aconnector = drmm_kzalloc(drm, sizeof(*aconnector), 
>>>>>> GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, aconnector);
>>>>>>         KUNIT_ASSERT_EQ(test,
>>>>>> @@ -3103,7 +3104,7 @@ static struct dm_test_panel_ctx 
>>>>>> *dm_test_panel_ctx_alloc(struct kunit *test)
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, prop);
>>>>>>       ctx->drm->mode_config.panel_type_property = prop;
>>>>>>   -    ctx->aconnector = kunit_kzalloc(test, sizeof(*ctx- 
>>>>>> >aconnector), GFP_KERNEL);
>>>>>> +    ctx->aconnector = drmm_kzalloc(ctx->drm, sizeof(*ctx- 
>>>>>> >aconnector), GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, ctx->aconnector);
>>>>>>       KUNIT_ASSERT_EQ(test,
>>>>>>           drmm_connector_init(ctx->drm, &ctx->aconnector->base,
>>>>>> @@ -3112,7 +3113,7 @@ static struct dm_test_panel_ctx 
>>>>>> *dm_test_panel_ctx_alloc(struct kunit *test)
>>>>>> drm_object_attach_property(&ctx->aconnector->base.base, prop,
>>>>>>                      DRM_MODE_PANEL_TYPE_UNKNOWN);
>>>>>>   -    ctx->link = kunit_kzalloc(test, sizeof(*ctx->link), 
>>>>>> GFP_KERNEL);
>>>>>> +    ctx->link = drmm_kzalloc(ctx->drm, sizeof(*ctx->link), 
>>>>>> GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, ctx->link);
>>>>>>       ctx->aconnector->dc_link = ctx->link;
>>>>>>   @@ -3376,14 +3377,14 @@ static struct dm_test_fill_ctx 
>>>>>> *dm_test_fill_ctx_alloc(struct kunit *test)
>>>>>>                                  DRIVER_MODESET);
>>>>>>       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->drm);
>>>>>>   -    ctx->aconnector = kunit_kzalloc(test, sizeof(*ctx- 
>>>>>> >aconnector), GFP_KERNEL);
>>>>>> +    ctx->aconnector = drmm_kzalloc(ctx->drm, sizeof(*ctx- 
>>>>>> >aconnector), GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, ctx->aconnector);
>>>>>>       KUNIT_ASSERT_EQ(test,
>>>>>>           drmm_connector_init(ctx->drm, &ctx->aconnector->base,
>>>>>>                       &dm_test_connector_funcs,
>>>>>>                       DRM_MODE_CONNECTOR_DisplayPort, NULL), 0);
>>>>>>   -    ctx->conn_state = kunit_kzalloc(test, sizeof(*ctx- 
>>>>>> >conn_state), GFP_KERNEL);
>>>>>> +    ctx->conn_state = drmm_kzalloc(ctx->drm, sizeof(*ctx- 
>>>>>> >conn_state), GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, ctx->conn_state);
>>>>>>       ctx->stream = kunit_kzalloc(test, sizeof(*ctx->stream), 
>>>>>> GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, ctx->stream);
>>>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/ 
>>>>>> amdgpu_dm_kunit_helpers.c 
>>>>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/ 
>>>>>> tests/amdgpu_dm_kunit_helpers.c
>>>>>> index 58615cdbe854..7d5e3823b33b 100644
>>>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/ 
>>>>>> amdgpu_dm_kunit_helpers.c
>>>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/ 
>>>>>> amdgpu_dm_kunit_helpers.c
>>>>>> @@ -8,6 +8,7 @@
>>>>>>   #include <kunit/test.h>
>>>>>>   #include <linux/module.h>
>>>>>>   #include <drm/drm_kunit_helpers.h>
>>>>>> +#include <drm/drm_managed.h>
>>>>>>     #include "dc.h"
>>>>>>   #include "core_types.h"
>>>>>> @@ -127,7 +128,7 @@ struct amdgpu_dm_connector 
>>>>>> *dm_kunit_alloc_connector(struct kunit *test,
>>>>>>   {
>>>>>>       struct amdgpu_dm_connector *aconnector;
>>>>>>   -    aconnector = kunit_kzalloc(test, sizeof(*aconnector), 
>>>>>> GFP_KERNEL);
>>>>>> +    aconnector = drmm_kzalloc(adev_to_drm(adev), 
>>>>>> sizeof(*aconnector), GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, aconnector);
>>>>>>         if (adev)
>>>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/ 
>>>>>> amdgpu_dm_wb_test.c 
>>>>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/ amdgpu_dm_wb_test.c
>>>>>> index b43bc244487e..3454cf371414 100644
>>>>>> --- 
>>>>>> a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_wb_test.c
>>>>>> +++ 
>>>>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_wb_test.c
>>>>>> @@ -12,6 +12,7 @@
>>>>>>   #include <drm/drm_fourcc.h>
>>>>>>   #include <drm/drm_framebuffer.h>
>>>>>>   #include <drm/drm_kunit_helpers.h>
>>>>>> +#include <drm/drm_managed.h>
>>>>>>   #include <drm/drm_mode.h>
>>>>>>   #include <drm/drm_modes.h>
>>>>>>   #include <drm/drm_writeback.h>
>>>>>> @@ -266,7 +267,7 @@ static void 
>>>>>> dm_test_wb_get_modes_returns_modes(struct kunit *test)
>>>>>>                              DRIVER_MODESET | DRIVER_ATOMIC);
>>>>>>       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
>>>>>>   -    connector = kunit_kzalloc(test, sizeof(*connector), 
>>>>>> GFP_KERNEL);
>>>>>> +    connector = drmm_kzalloc(drm, sizeof(*connector), GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, connector);
>>>>>>         drmm_connector_init(drm, connector, 
>>>>>> &dm_wb_test_connector_funcs,
>>>>>> @@ -301,7 +302,7 @@ static void 
>>>>>> dm_test_wb_get_modes_bounded_by_max(struct kunit *test)
>>>>>>                              DRIVER_MODESET | DRIVER_ATOMIC);
>>>>>>       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
>>>>>>   -    connector = kunit_kzalloc(test, sizeof(*connector), 
>>>>>> GFP_KERNEL);
>>>>>> +    connector = drmm_kzalloc(drm, sizeof(*connector), GFP_KERNEL);
>>>>>>       KUNIT_ASSERT_NOT_NULL(test, connector);
>>>>>>         drmm_connector_init(drm, connector, 
>>>>>> &dm_wb_test_connector_funcs,
>>>>>
>>>>
>>>
>>
>