All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] dma-buf: fix stack corruption in dma_fence_chain_release
       [not found] <20190805073657.1389-1-christian.koenig@amd.com>
@ 2019-08-05  8:23 ` Lionel Landwerlin
  2019-08-05 12:03 ` Lionel Landwerlin
  1 sibling, 0 replies; 5+ messages in thread
From: Lionel Landwerlin @ 2019-08-05  8:23 UTC (permalink / raw)
  To: Christian König, dri-devel, david1.zhou

On 05/08/2019 10:36, Christian König wrote:
> We can't free up the chain using recursion or we run into a stack overflow.
>
> Manually free up the dangling chain nodes to avoid recursion.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>


That definitely makes sense to me, but I'm not an expert in RCU foo :/


Acked-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>


I guess this deserves a


Fixes: 7bf60c52e0 ("dma-buf: add new dma_fence_chain container v7")


> ---
>   drivers/dma-buf/dma-fence-chain.c | 24 +++++++++++++++++++++++-
>   1 file changed, 23 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma-buf/dma-fence-chain.c b/drivers/dma-buf/dma-fence-chain.c
> index b5089f64be2a..44a741677d25 100644
> --- a/drivers/dma-buf/dma-fence-chain.c
> +++ b/drivers/dma-buf/dma-fence-chain.c
> @@ -178,8 +178,30 @@ static bool dma_fence_chain_signaled(struct dma_fence *fence)
>   static void dma_fence_chain_release(struct dma_fence *fence)
>   {
>   	struct dma_fence_chain *chain = to_dma_fence_chain(fence);
> +	struct dma_fence *prev;
> +
> +	/* Manually unlink the chain as much as possible to avoid recursion
> +	 * and potential stack overflow.
> +	 */
> +	while ((prev = rcu_dereference_protected(chain->prev, true))) {
> +		struct dma_fence_chain *prev_chain;
> +
> +		if (kref_read(&prev->refcount) > 1)
> +		       break;
> +
> +		prev_chain = to_dma_fence_chain(prev);
> +		if (!prev_chain)
> +			break;
> +
> +		/* No need for atomic operations since we hold the last
> +		 * reference to prev_chain.
> +		 */
> +		chain->prev = prev_chain->prev;
> +		RCU_INIT_POINTER(prev_chain->prev, NULL);
> +		dma_fence_put(prev);
> +	}
> +	dma_fence_put(prev);
>   
> -	dma_fence_put(rcu_dereference_protected(chain->prev, true));
>   	dma_fence_put(chain->fence);
>   	dma_fence_free(fence);
>   }


_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] dma-buf: fix stack corruption in dma_fence_chain_release
       [not found] <20190805073657.1389-1-christian.koenig@amd.com>
  2019-08-05  8:23 ` [PATCH] dma-buf: fix stack corruption in dma_fence_chain_release Lionel Landwerlin
@ 2019-08-05 12:03 ` Lionel Landwerlin
  2019-08-05 13:02   ` Christian König
  1 sibling, 1 reply; 5+ messages in thread
From: Lionel Landwerlin @ 2019-08-05 12:03 UTC (permalink / raw)
  To: Christian König, dri-devel, david1.zhou

By any change, did you run into this with a CTS test whose name ends 
with ".chain" ? :)

-Lionel

On 05/08/2019 10:36, Christian König wrote:
> We can't free up the chain using recursion or we run into a stack overflow.
>
> Manually free up the dangling chain nodes to avoid recursion.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>   drivers/dma-buf/dma-fence-chain.c | 24 +++++++++++++++++++++++-
>   1 file changed, 23 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma-buf/dma-fence-chain.c b/drivers/dma-buf/dma-fence-chain.c
> index b5089f64be2a..44a741677d25 100644
> --- a/drivers/dma-buf/dma-fence-chain.c
> +++ b/drivers/dma-buf/dma-fence-chain.c
> @@ -178,8 +178,30 @@ static bool dma_fence_chain_signaled(struct dma_fence *fence)
>   static void dma_fence_chain_release(struct dma_fence *fence)
>   {
>   	struct dma_fence_chain *chain = to_dma_fence_chain(fence);
> +	struct dma_fence *prev;
> +
> +	/* Manually unlink the chain as much as possible to avoid recursion
> +	 * and potential stack overflow.
> +	 */
> +	while ((prev = rcu_dereference_protected(chain->prev, true))) {
> +		struct dma_fence_chain *prev_chain;
> +
> +		if (kref_read(&prev->refcount) > 1)
> +		       break;
> +
> +		prev_chain = to_dma_fence_chain(prev);
> +		if (!prev_chain)
> +			break;
> +
> +		/* No need for atomic operations since we hold the last
> +		 * reference to prev_chain.
> +		 */
> +		chain->prev = prev_chain->prev;
> +		RCU_INIT_POINTER(prev_chain->prev, NULL);
> +		dma_fence_put(prev);
> +	}
> +	dma_fence_put(prev);
>   
> -	dma_fence_put(rcu_dereference_protected(chain->prev, true));
>   	dma_fence_put(chain->fence);
>   	dma_fence_free(fence);
>   }


_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] dma-buf: fix stack corruption in dma_fence_chain_release
  2019-08-05 12:03 ` Lionel Landwerlin
@ 2019-08-05 13:02   ` Christian König
  2019-08-05 13:32     ` Lionel Landwerlin
  0 siblings, 1 reply; 5+ messages in thread
From: Christian König @ 2019-08-05 13:02 UTC (permalink / raw)
  To: Lionel Landwerlin, dri-devel, david1.zhou

Not even remotely :)I tested this with my own crafted code inside the 
kernel.

It's probably quite some hassle to actually trigger this problem from 
userspace and I only found it because I created a very very long 
sequence chain by accident.

Christian.

Am 05.08.19 um 14:03 schrieb Lionel Landwerlin:
> By any change, did you run into this with a CTS test whose name ends 
> with ".chain" ? :)
>
> -Lionel
>
> On 05/08/2019 10:36, Christian König wrote:
>> We can't free up the chain using recursion or we run into a stack 
>> overflow.
>>
>> Manually free up the dangling chain nodes to avoid recursion.
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
>> ---
>>   drivers/dma-buf/dma-fence-chain.c | 24 +++++++++++++++++++++++-
>>   1 file changed, 23 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/dma-buf/dma-fence-chain.c 
>> b/drivers/dma-buf/dma-fence-chain.c
>> index b5089f64be2a..44a741677d25 100644
>> --- a/drivers/dma-buf/dma-fence-chain.c
>> +++ b/drivers/dma-buf/dma-fence-chain.c
>> @@ -178,8 +178,30 @@ static bool dma_fence_chain_signaled(struct 
>> dma_fence *fence)
>>   static void dma_fence_chain_release(struct dma_fence *fence)
>>   {
>>       struct dma_fence_chain *chain = to_dma_fence_chain(fence);
>> +    struct dma_fence *prev;
>> +
>> +    /* Manually unlink the chain as much as possible to avoid recursion
>> +     * and potential stack overflow.
>> +     */
>> +    while ((prev = rcu_dereference_protected(chain->prev, true))) {
>> +        struct dma_fence_chain *prev_chain;
>> +
>> +        if (kref_read(&prev->refcount) > 1)
>> +               break;
>> +
>> +        prev_chain = to_dma_fence_chain(prev);
>> +        if (!prev_chain)
>> +            break;
>> +
>> +        /* No need for atomic operations since we hold the last
>> +         * reference to prev_chain.
>> +         */
>> +        chain->prev = prev_chain->prev;
>> +        RCU_INIT_POINTER(prev_chain->prev, NULL);
>> +        dma_fence_put(prev);
>> +    }
>> +    dma_fence_put(prev);
>>   -    dma_fence_put(rcu_dereference_protected(chain->prev, true));
>>       dma_fence_put(chain->fence);
>>       dma_fence_free(fence);
>>   }
>
>

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] dma-buf: fix stack corruption in dma_fence_chain_release
  2019-08-05 13:02   ` Christian König
@ 2019-08-05 13:32     ` Lionel Landwerlin
  2019-08-05 16:30       ` Daniel Vetter
  0 siblings, 1 reply; 5+ messages in thread
From: Lionel Landwerlin @ 2019-08-05 13:32 UTC (permalink / raw)
  To: christian.koenig, dri-devel, david1.zhou

That one test creates a 32k chain of fences I think.
Anyway my kernel crash was unrelated ;)

-Lionel

On 05/08/2019 16:02, Christian König wrote:
> Not even remotely :)I tested this with my own crafted code inside the 
> kernel.
>
> It's probably quite some hassle to actually trigger this problem from 
> userspace and I only found it because I created a very very long 
> sequence chain by accident.
>
> Christian.
>
> Am 05.08.19 um 14:03 schrieb Lionel Landwerlin:
>> By any change, did you run into this with a CTS test whose name ends 
>> with ".chain" ? :)
>>
>> -Lionel
>>
>> On 05/08/2019 10:36, Christian König wrote:
>>> We can't free up the chain using recursion or we run into a stack 
>>> overflow.
>>>
>>> Manually free up the dangling chain nodes to avoid recursion.
>>>
>>> Signed-off-by: Christian König <christian.koenig@amd.com>
>>> ---
>>>   drivers/dma-buf/dma-fence-chain.c | 24 +++++++++++++++++++++++-
>>>   1 file changed, 23 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/dma-buf/dma-fence-chain.c 
>>> b/drivers/dma-buf/dma-fence-chain.c
>>> index b5089f64be2a..44a741677d25 100644
>>> --- a/drivers/dma-buf/dma-fence-chain.c
>>> +++ b/drivers/dma-buf/dma-fence-chain.c
>>> @@ -178,8 +178,30 @@ static bool dma_fence_chain_signaled(struct 
>>> dma_fence *fence)
>>>   static void dma_fence_chain_release(struct dma_fence *fence)
>>>   {
>>>       struct dma_fence_chain *chain = to_dma_fence_chain(fence);
>>> +    struct dma_fence *prev;
>>> +
>>> +    /* Manually unlink the chain as much as possible to avoid 
>>> recursion
>>> +     * and potential stack overflow.
>>> +     */
>>> +    while ((prev = rcu_dereference_protected(chain->prev, true))) {
>>> +        struct dma_fence_chain *prev_chain;
>>> +
>>> +        if (kref_read(&prev->refcount) > 1)
>>> +               break;
>>> +
>>> +        prev_chain = to_dma_fence_chain(prev);
>>> +        if (!prev_chain)
>>> +            break;
>>> +
>>> +        /* No need for atomic operations since we hold the last
>>> +         * reference to prev_chain.
>>> +         */
>>> +        chain->prev = prev_chain->prev;
>>> +        RCU_INIT_POINTER(prev_chain->prev, NULL);
>>> +        dma_fence_put(prev);
>>> +    }
>>> +    dma_fence_put(prev);
>>>   -    dma_fence_put(rcu_dereference_protected(chain->prev, true));
>>>       dma_fence_put(chain->fence);
>>>       dma_fence_free(fence);
>>>   }
>>
>>
>
>

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] dma-buf: fix stack corruption in dma_fence_chain_release
  2019-08-05 13:32     ` Lionel Landwerlin
@ 2019-08-05 16:30       ` Daniel Vetter
  0 siblings, 0 replies; 5+ messages in thread
From: Daniel Vetter @ 2019-08-05 16:30 UTC (permalink / raw)
  To: Lionel Landwerlin; +Cc: christian.koenig, dri-devel

On Mon, Aug 05, 2019 at 04:32:20PM +0300, Lionel Landwerlin wrote:
> That one test creates a 32k chain of fences I think.
> Anyway my kernel crash was unrelated ;)

Hm I'd expect that with clever use of vgem fake fences we should be able
to repro this bug here with an igt. Would be real nice, any takers?
-Daniel

> 
> -Lionel
> 
> On 05/08/2019 16:02, Christian König wrote:
> > Not even remotely :)I tested this with my own crafted code inside the
> > kernel.
> > 
> > It's probably quite some hassle to actually trigger this problem from
> > userspace and I only found it because I created a very very long
> > sequence chain by accident.
> > 
> > Christian.
> > 
> > Am 05.08.19 um 14:03 schrieb Lionel Landwerlin:
> > > By any change, did you run into this with a CTS test whose name ends
> > > with ".chain" ? :)
> > > 
> > > -Lionel
> > > 
> > > On 05/08/2019 10:36, Christian König wrote:
> > > > We can't free up the chain using recursion or we run into a
> > > > stack overflow.
> > > > 
> > > > Manually free up the dangling chain nodes to avoid recursion.
> > > > 
> > > > Signed-off-by: Christian König <christian.koenig@amd.com>
> > > > ---
> > > >   drivers/dma-buf/dma-fence-chain.c | 24 +++++++++++++++++++++++-
> > > >   1 file changed, 23 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/dma-buf/dma-fence-chain.c
> > > > b/drivers/dma-buf/dma-fence-chain.c
> > > > index b5089f64be2a..44a741677d25 100644
> > > > --- a/drivers/dma-buf/dma-fence-chain.c
> > > > +++ b/drivers/dma-buf/dma-fence-chain.c
> > > > @@ -178,8 +178,30 @@ static bool dma_fence_chain_signaled(struct
> > > > dma_fence *fence)
> > > >   static void dma_fence_chain_release(struct dma_fence *fence)
> > > >   {
> > > >       struct dma_fence_chain *chain = to_dma_fence_chain(fence);
> > > > +    struct dma_fence *prev;
> > > > +
> > > > +    /* Manually unlink the chain as much as possible to avoid
> > > > recursion
> > > > +     * and potential stack overflow.
> > > > +     */
> > > > +    while ((prev = rcu_dereference_protected(chain->prev, true))) {
> > > > +        struct dma_fence_chain *prev_chain;
> > > > +
> > > > +        if (kref_read(&prev->refcount) > 1)
> > > > +               break;
> > > > +
> > > > +        prev_chain = to_dma_fence_chain(prev);
> > > > +        if (!prev_chain)
> > > > +            break;
> > > > +
> > > > +        /* No need for atomic operations since we hold the last
> > > > +         * reference to prev_chain.
> > > > +         */
> > > > +        chain->prev = prev_chain->prev;
> > > > +        RCU_INIT_POINTER(prev_chain->prev, NULL);
> > > > +        dma_fence_put(prev);
> > > > +    }
> > > > +    dma_fence_put(prev);
> > > >   -    dma_fence_put(rcu_dereference_protected(chain->prev, true));
> > > >       dma_fence_put(chain->fence);
> > > >       dma_fence_free(fence);
> > > >   }
> > > 
> > > 
> > 
> > 
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-08-05 16:30 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20190805073657.1389-1-christian.koenig@amd.com>
2019-08-05  8:23 ` [PATCH] dma-buf: fix stack corruption in dma_fence_chain_release Lionel Landwerlin
2019-08-05 12:03 ` Lionel Landwerlin
2019-08-05 13:02   ` Christian König
2019-08-05 13:32     ` Lionel Landwerlin
2019-08-05 16:30       ` Daniel Vetter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.