summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2026-07-15 08:42:44 -0700
committerJonathan Cameron <jonathan.cameron@oss.qualcomm.com>2026-08-07 23:51:03 +0100
commitf25ec4627d935dedfb5fe83bd2c2678cdcc19611 (patch)
tree486bbc66eda4a2f14944ed19da88a44e7fe2052d /drivers
parent6288b593e76eb10329326f2cd51e32557203b9e5 (diff)
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: 3e26d9f08fbe ("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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iio/industrialio-buffer.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index 04b3916f89e2..31c06bffdce8 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -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)