mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
iio: buffer: Tie IIO dma fence lock lifetime to the fence
The `iio_dma_fence` implementation currently uses a lock embedded in the
`iio_dmabuf_priv`. But the `iio_dma_fence` can outlive the
`iio_dmabuf_priv`, which can cause a use-after-free.
Tie the lifetime of the lock to the lifetime of the fence by embedding them
in the same struct.
We can't just hold a reference to the `iio_dmabuf_priv` from the
`iio_dma_fence` since `iio_buffer_dmabuf_release()` might sleep and the
fence release callback is not allowed to sleep.
Note that the `dma_fence` framework now has an internal lock that gets used
when the passing `NULL` for `lock` in `dma_fence_init()`, but in order to
allow this patch to be backportable use an external lock.
Reported-by: codex:gpt-5.6
Fixes: 3e26d9f08f ("iio: core: Add new DMABUF interface infrastructure")
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
This commit is contained in:
parent
6288b593e7
commit
f25ec4627d
|
|
@ -47,9 +47,6 @@ struct iio_dmabuf_priv {
|
|||
|
||||
u64 context;
|
||||
|
||||
/* Spinlock used for locking the dma_fence */
|
||||
spinlock_t lock;
|
||||
|
||||
struct dma_buf_attachment *attach;
|
||||
struct sg_table *sgt;
|
||||
enum dma_data_direction dir;
|
||||
|
|
@ -58,6 +55,7 @@ struct iio_dmabuf_priv {
|
|||
|
||||
struct iio_dma_fence {
|
||||
struct dma_fence base;
|
||||
spinlock_t lock; /* protects base */
|
||||
struct iio_dmabuf_priv *priv;
|
||||
struct work_struct work;
|
||||
};
|
||||
|
|
@ -1706,7 +1704,6 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
|
|||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
priv->context = dma_fence_context_alloc(1);
|
||||
|
||||
dmabuf = dma_buf_get(fd);
|
||||
|
|
@ -1896,6 +1893,8 @@ static int iio_buffer_enqueue_dmabuf(struct iio_dev_buffer_pair *ib,
|
|||
goto err_attachment_put;
|
||||
}
|
||||
|
||||
spin_lock_init(&fence->lock);
|
||||
|
||||
fence->priv = priv;
|
||||
|
||||
seqno = atomic_add_return(1, &priv->seqno);
|
||||
|
|
@ -1906,7 +1905,7 @@ static int iio_buffer_enqueue_dmabuf(struct iio_dev_buffer_pair *ib,
|
|||
* the dma_fence.
|
||||
*/
|
||||
dma_fence_init(&fence->base, &iio_buffer_dma_fence_ops,
|
||||
&priv->lock, priv->context, seqno);
|
||||
&fence->lock, priv->context, seqno);
|
||||
|
||||
ret = iio_dma_resv_lock(dmabuf, nonblock);
|
||||
if (ret)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user