Hi Laurent,

Sorry for the late reply.
Thank you very much for noticing the issue.

>>>> +static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv)
>>>> +{
>>>> +  struct vb2_dc_buf *buf = buf_priv;
>>>> +  struct dma_buf *dbuf;
>>>> +
>>>> +  if (buf->dma_buf)
>>>> +          return buf->dma_buf;
>>>
>>> Can't there be a race condition here if the user closes the DMABUF file
>>> handle before vb2 core calls dma_buf_fd() ?
>>
>> The user cannot access the file until it is associated with a file
>> descriptor. How can the user close it? Could you give me a more detailed
>> description of this potential race condition?
> 
> Let's assume the V4L2 buffer has already been exported once. buf->dma_buf is 
> set to a non-NULL value, and the application has an open file handle for the 
> buffer. The application then tries to export the buffer a second time. 
> vb2_dc_get_dmabuf() gets called, checks buf->dma_buf and returns it as it's 
> non-NULL. Right after that, before the vb2 core calls dma_buf_fd() on the 
> struct dma_buf, the application closes the file handle to the exported 
> buffer. 
> The struct dma_buf object gets freed, as the reference count drops to 0.

I am not sure if reference counter drops to 0 in this case. Notice that after
first dma_buf_export the dma_buf's refcnt is 1, after first dma_buf_fd it goes
to 2. After closing a file handle the refcnt drops back to 1 so the file
(and dma_buf) is not released. Therefore IMO there no dangling pointer issue.

However it looks that there is a circular reference between vb2_dc_buf and 
dma_buf.
vb2_dc_buf::dma_buf is pointing to dma_buf with reference taken at 
dma_buf_export.
On the other hand the dma_buf->priv is pointing to vb2_dc_buf with reference
taken at atomic_inc(&buf->refcount) in vb2_dc_get_dmabuf.

The circular reference leads into resource leakage.
The problem could be fixed by dropping caching of dma_buf pointer.
The new dma_buf would be created and exported at every export event.
The dma_buf_put would be called in vb2_expbuf just after
successful dma_buf_fd.

Do you have any ideas how I could deal with resource leakage/dangling problems
without creating a new dma_buf instance at every export event?

Regards,
Tomasz Stanislawski


> vb2 core will then try to call dma_buf_fd() on a dma_buf object that has been 
> freed.
> 
>>>> +  /* dmabuf keeps reference to vb2 buffer */
>>>> +  atomic_inc(&buf->refcount);
>>>> +  dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, 0);
>>>> +  if (IS_ERR(dbuf)) {
>>>> +          atomic_dec(&buf->refcount);
>>>> +          return NULL;
>>>> +  }
>>>> +
>>>> +  buf->dma_buf = dbuf;
>>>> +
>>>> +  return dbuf;
>>>> +}
> 

Reply via email to