From: Alejandro Colomar <alx+linux-hardening@kernel.org>
To: Rosen Penev <rosenp@gmail.com>, Kees Cook <kees@kernel.org>
Cc: dri-devel@lists.freedesktop.org, Inki Dae <inki.dae@samsung.com>,
Seung-Woo Kim <sw0312.kim@samsung.com>,
Kyungmin Park <kyungmin.park@samsung.com>,
David Airlie <airlied@gmail.com>,
Simona Vetter <simona@ffwll.ch>,
Krzysztof Kozlowski <krzk@kernel.org>,
Peter Griffin <peter.griffin@linaro.org>,
Alim Akhtar <alim.akhtar@samsung.com>,
Kees Cook <kees@kernel.org>,
"Gustavo A. R. Silva" <gustavoars@kernel.org>,
"moderated list:ARM/SAMSUNG S3C,
S5P AND EXYNOS ARM ARCHITECTURES"
<linux-arm-kernel@lists.infradead.org>,
"open list:ARM/SAMSUNG S3C,
S5P AND EXYNOS ARM ARCHITECTURES"
<linux-samsung-soc@vger.kernel.org>,
open list <linux-kernel@vger.kernel.org>,
"open list:KERNEL HARDENING (not covered by other
areas):Keyword:b__counted_by(_le|_be|_ptr)?b"
<linux-hardening@vger.kernel.org>
Subject: *allocflex() (was: [PATCH] drm/exynos: fimc: allocate formats as a flexible array member)
Date: Mon, 5 Oct 2026 10:07:02 +0200 [thread overview]
Message-ID: <asNWiJT4Io2R7xGt@debian> (raw)
In-Reply-To: <20261005001118.576198-1-rosenp@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 5544 bytes --]
Hi,
> Date: 2026-10-04 17:11:18-0700
> From: Rosen Penev <rosenp@gmail.com>
>
> The formats array is allocated separately with devm_kcalloc() and only
> referenced through the fimc_context. Make it a flexible array member at
> the end of the context and allocate both in one go with struct_size().
>
> Annotate it with __counted_by(num_formats) so the array accesses can be
> bounds checked with FORTIFY_SOURCE and UBSAN_BOUNDS.
>
> Assisted-by: LLM
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
> drivers/gpu/drm/exynos/exynos_drm_fimc.c | 17 +++++------------
> 1 file changed, 5 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
> index 09e33a26caaf..079d24d0671c 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
> @@ -99,7 +99,6 @@ struct fimc_context {
> void *dma_priv;
> struct device *dev;
> struct exynos_drm_ipp_task *task;
> - struct exynos_drm_ipp_formats *formats;
> unsigned int num_formats;
>
> void __iomem *regs;
> @@ -108,6 +107,7 @@ struct fimc_context {
> struct fimc_scaler sc;
> int id;
> int irq;
> + struct exynos_drm_ipp_formats formats[] __counted_by(num_formats);
> };
>
> static u32 fimc_read(struct fimc_context *ctx, u32 reg)
> @@ -1273,20 +1273,16 @@ static int fimc_probe(struct platform_device *pdev)
> if (exynos_drm_check_fimc_device(dev) != 0)
> return -ENODEV;
>
> - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> + num_formats = ARRAY_SIZE(fimc_formats) + ARRAY_SIZE(fimc_tiled_formats);
> + ctx = devm_kzalloc(dev, struct_size(ctx, formats, num_formats), GFP_KERNEL);
Unrelated to this patch, but this has triggered my attention.
I have been recently researching into allocation of FAMs, trying to make
them more type safe, and found it safer to have a specialized API for
such allocations, whose pseudo-prototype would look like this:
T *mallocflex(typename S, size_t n, flex);
A devm_kzallocflex() could then have an extra 'dev' parameter at the
front, and the usual 'gpf' one at the end. It could be used here as:
n = ARRAY_SIZE(fimc_formats) + ARRAY_SIZE(fimc_tiled_formats);
ctx = devm_kzallocflex(dev, struct fimc_context, n, formats, GFP_KERNEL);
Kees, do you think we could add something like this?
Here's a small program showing how it could be implemented:
$ cat fam.c
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
#define typeof_typename(T) typeof(*(typeof(T) *){_Generic(0, T: NULL, default: NULL)})
#define memberof(T, member) ((T){}.member)
#define sizeof_flex(T, n, fam) MAX(sizeof(T), offsetof(T, fam[n]))
#define ptr_cast(T, p) rvalue((typeof_typename(T) *){(p)})
#define rvalue(lv) ((void)0, (lv))
#define reallocflex_T(p, S, n, flex) reallocflex_T_(p, typeof_typename(S), n, flex)
#define reallocflex_T_(p, S, n, flex) \
( \
_Generic(p, S *: (void)0), \
ptr_cast(S, reallocflex_T__(p, S, n, flex)) \
)
#define reallocflex_T__(p, S, n, f) \
( \
reallocflex(p, sizeof(S), offsetof(S, f), n, sizeof(memberof(S, f)[0]))\
)
#define mallocflex_T(S, n, flex) \
( \
ptr_cast(S, reallocflex_T__(NULL, S, n, flex)) \
)
void *
reallocflex(void *p, size_t headsize, size_t off, size_t n, size_t eltsize)
{
if (n != 0 && eltsize > SIZE_MAX / n) {
errno = ENOMEM;
return NULL;
}
if (off > SIZE_MAX - n*eltsize) {
errno = ENOMEM;
return NULL;
}
if (off > headsize) {
errno = ENOMEM;
return NULL;
}
#ifndef NDEBUG
printf("%zu (%zu, %zu, %zu, %zu)\n", MAX(headsize, off + n * eltsize), headsize, off, n, eltsize);
#endif
return realloc(p, MAX(headsize, off + n * eltsize));
}
struct s {
long a;
char b,c,d;
int f[];
};
int
main(void)
{
struct s *p;
printf("s: %zu\n", sizeof(struct s));
printf("o: %zu\n", offsetof(struct s, f));
p = mallocflex_T(struct s, 2, f);
p = reallocflex_T(p, struct s, 0, f);
p = reallocflex_T(p, struct s, 1, f);
bzero(p, sizeof_flex(struct s, 1, f));
free(p);
}
Have a lovely day!
Alex
> if (!ctx)
> return -ENOMEM;
>
> + ctx->num_formats = num_formats;
> + formats = ctx->formats;
> ctx->dev = dev;
> ctx->id = of_alias_get_id(dev->of_node, "fimc");
>
> - /* construct formats/limits array */
> - num_formats = ARRAY_SIZE(fimc_formats) + ARRAY_SIZE(fimc_tiled_formats);
> - formats = devm_kcalloc(dev, num_formats, sizeof(*formats),
> - GFP_KERNEL);
> - if (!formats)
> - return -ENOMEM;
> -
> /* linear formats */
> if (ctx->id < 3) {
> limits = fimc_4210_limits_v1;
> @@ -1320,9 +1316,6 @@ static int fimc_probe(struct platform_device *pdev)
> formats[j].num_limits = num_limits;
> }
>
> - ctx->formats = formats;
> - ctx->num_formats = num_formats;
> -
> /* resource memory */
> ctx->regs = devm_platform_ioremap_resource(pdev, 0);
> if (IS_ERR(ctx->regs))
> --
> 2.56.0
>
>
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
prev parent reply other threads:[~2026-10-05 8:07 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-05 0:11 [PATCH] drm/exynos: fimc: allocate formats as a flexible array member Rosen Penev
2026-10-05 8:07 ` Alejandro Colomar [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=asNWiJT4Io2R7xGt@debian \
--to=alx+linux-hardening@kernel.org \
--cc=airlied@gmail.com \
--cc=alim.akhtar@samsung.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=gustavoars@kernel.org \
--cc=inki.dae@samsung.com \
--cc=kees@kernel.org \
--cc=krzk@kernel.org \
--cc=kyungmin.park@samsung.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-samsung-soc@vger.kernel.org \
--cc=peter.griffin@linaro.org \
--cc=rosenp@gmail.com \
--cc=simona@ffwll.ch \
--cc=sw0312.kim@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.