possible use-after-free in amdgpu_dm

Andrey Grodzovsky Andrey.Grodzovsky at amd.com
Tue Oct 17 17:42:56 UTC 2017



On 10/17/2017 01:36 PM, Tom St Denis wrote:
> On 17/10/17 01:34 PM, Andrey Grodzovsky wrote:
>>
>>
>> On 10/17/2017 01:25 PM, Tom St Denis wrote:
>>> On 17/10/17 01:23 PM, Tom St Denis wrote:
>>>> On 17/10/17 01:18 PM, Christian König wrote:
>>>>> Am 17.10.2017 um 16:10 schrieb Tom St Denis:
>>>>>> In this block of code:
>>>>>>
>>>>>> void amdgpu_dm_connector_funcs_reset(struct drm_connector 
>>>>>> *connector)
>>>>>> {
>>>>>>     struct dm_connector_state *state =
>>>>>>         to_dm_connector_state(connector->state);
>>>>>>
>>>>>>     kfree(state);
>>>>>>
>>>>>>     state = kzalloc(sizeof(*state), GFP_KERNEL);
>>>>>>
>>>>>>
>>>>>> The value of state is never compared with NULL and moreso the 
>>>>>> value of connector->state is never written to if NULL. Wouldn't 
>>>>>> this mean the pointer points to freed memory?
>>>>>
>>>>> Why should we compare the value of state to NULL? What's done here 
>>>>> is just to get the size of the type state points to.
>>>>>
>>>>> Not sure if that is really covered by the C standard, but in 
>>>>> practice it works fine even when state is NULL.
>>>>
>>>> Hi Christian,
>>>>
>>>>
>>>> Oh sorry no the issue isn't with the sizeof (that's perfectly fine 
>>>> since the standard says the pointer won't be dereferenced).
>>>>
>>>> The issue is later on in the function there's this statement:
>>>>
>>>>          connector->state = &state->base;
>>>>
>>>> Where "base" is first item in the struct so it's effectively just 
>>>> "connector->state = &state".
>>>>
>>>> This means that the value of "connector->state" is stale since the 
>>>> pointer was kfree'ed right (if the alloc fails) which could lead to 
>>>> a use-after-free error (I don't know where this function lies in 
>>>> the rest of the code paths but it seems wrong either way).
>>>
>>>
>>> Sorry I think I might be explaining this poorly.
>>>
>>> In the case the alloc succeeds the pointer is updated and everything 
>>> is fine.
>>>
>>> IF the alloc fails the pointer (connector->state) is not updated and 
>>> the value points to freed memory.
>>
>> Indeed an issue, there should be a big WARN_ON or error here for such 
>> a case. In general this hook is called from drm_mode_config_reset 
>> which is used to reset SW and HW states on loading or resetting due 
>> to GPU reset or resume from suspend. I think we only use it on load.
>
>
> I'm not sure if that's a WARN_ON or simply a BUG_ON since I don't get 
> how the dm layer continues at this point.
>
> Alternatively, we could put a WARN_ON and set the pointer to NULL and 
> let it handle it higher in the call stack.
>
> Would you like me to draft a commit for the latter?

IMHO It's more of a BUG_ON situation, this failure is not recoverable 
since the framework assumes a connector has a fresh state to start 
working on.

Andrey

>
> Cheers,
> Tom



More information about the amd-gfx mailing list