diff options
author | Christophe JAILLET <christophe.jaillet@wanadoo.fr> | 2023-10-07 14:13:10 +0300 |
---|---|---|
committer | Vinod Koul <vkoul@kernel.org> | 2023-10-09 08:17:26 +0300 |
commit | 0481291f0ccbc5147635cf0eb108f9fe5a05ee7d (patch) | |
tree | deb32bfff86c301681ee9914137842e057822e83 /drivers/dma/pxa_dma.c | |
parent | 83c761f568733277ce1f7eb9dc9e890649c29a8c (diff) | |
download | linux-0481291f0ccbc5147635cf0eb108f9fe5a05ee7d.tar.xz |
dmaengine: pxa_dma: Annotate struct pxad_desc_sw with __counted_by
Prepare for the coming implementation by GCC and Clang of the __counted_by
attribute. Flexible array members annotated with __counted_by can have
their accesses bounds-checked at run-time checking via CONFIG_UBSAN_BOUNDS
(for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family
functions).
To do so, the code needs a little shuffling related to how hw_desc is used
and nb_desc incremented.
The one by one increment is needed for the error handling path, calling
pxad_free_desc(), to work correctly.
So, add a new intermediate variable, desc, to store the result of the
dma_pool_alloc() call.
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Reviewed-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/1c9ef22826f449a3756bb13a83494e9fe3e0be8b.1696676782.git.christophe.jaillet@wanadoo.fr
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/dma/pxa_dma.c')
-rw-r--r-- | drivers/dma/pxa_dma.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c index 94cef2905940..c6e2862896e3 100644 --- a/drivers/dma/pxa_dma.c +++ b/drivers/dma/pxa_dma.c @@ -91,7 +91,8 @@ struct pxad_desc_sw { bool cyclic; struct dma_pool *desc_pool; /* Channel's used allocator */ - struct pxad_desc_hw *hw_desc[]; /* DMA coherent descriptors */ + struct pxad_desc_hw *hw_desc[] __counted_by(nb_desc); + /* DMA coherent descriptors */ }; struct pxad_phy { @@ -739,6 +740,7 @@ pxad_alloc_desc(struct pxad_chan *chan, unsigned int nb_hw_desc) { struct pxad_desc_sw *sw_desc; dma_addr_t dma; + void *desc; int i; sw_desc = kzalloc(struct_size(sw_desc, hw_desc, nb_hw_desc), @@ -748,20 +750,21 @@ pxad_alloc_desc(struct pxad_chan *chan, unsigned int nb_hw_desc) sw_desc->desc_pool = chan->desc_pool; for (i = 0; i < nb_hw_desc; i++) { - sw_desc->hw_desc[i] = dma_pool_alloc(sw_desc->desc_pool, - GFP_NOWAIT, &dma); - if (!sw_desc->hw_desc[i]) { + desc = dma_pool_alloc(sw_desc->desc_pool, GFP_NOWAIT, &dma); + if (!desc) { dev_err(&chan->vc.chan.dev->device, "%s(): Couldn't allocate the %dth hw_desc from dma_pool %p\n", __func__, i, sw_desc->desc_pool); goto err; } + sw_desc->nb_desc++; + sw_desc->hw_desc[i] = desc; + if (i == 0) sw_desc->first = dma; else sw_desc->hw_desc[i - 1]->ddadr = dma; - sw_desc->nb_desc++; } return sw_desc; |