From: Kees Cook <keescook@chromium.org>
To: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: Haren Myneni <haren@us.ibm.com>,
Michael Ellerman <mpe@ellerman.id.au>,
Nicholas Piggin <npiggin@gmail.com>,
Christophe Leroy <christophe.leroy@csgroup.eu>,
"Aneesh Kumar K.V" <aneesh.kumar@kernel.org>,
"Naveen N. Rao" <naveen.n.rao@linux.ibm.com>,
Herbert Xu <herbert@gondor.apana.org.au>,
"David S. Miller" <davem@davemloft.net>,
linux-hardening@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH][next] crypto/nx: Avoid potential -Wflex-array-member-not-at-end warning
Date: Mon, 29 Apr 2024 10:05:01 -0700 [thread overview]
Message-ID: <202404290947.4A8BF6A6@keescook> (raw)
In-Reply-To: <ZgHmRNcR+a4EJX94@neat>
On Mon, Mar 25, 2024 at 03:01:56PM -0600, Gustavo A. R. Silva wrote:
> -Wflex-array-member-not-at-end is coming in GCC-14, and we are getting
> ready to enable it globally.
>
> Use the `__struct_group()` helper to separate the flexible array
> from the rest of the members in flexible `struct nx842_crypto_header`,
> through tagged `struct nx842_crypto_header_hdr`, and avoid embedding
> the flexible-array member in the middle of `struct nx842_crypto_ctx`.
>
> Also, use `container_of()` whenever we need to retrieve a pointer to
> the flexible structure.
>
> This code was detected with the help of Coccinelle, and audited and
> modified manually.
>
> Link: https://github.com/KSPP/linux/issues/202
> Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> ---
> drivers/crypto/nx/nx-842.c | 6 ++++--
> drivers/crypto/nx/nx-842.h | 11 +++++++----
> 2 files changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c
> index 2ab90ec10e61..82214cde2bcd 100644
> --- a/drivers/crypto/nx/nx-842.c
> +++ b/drivers/crypto/nx/nx-842.c
> @@ -251,7 +251,9 @@ int nx842_crypto_compress(struct crypto_tfm *tfm,
> u8 *dst, unsigned int *dlen)
> {
> struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
> - struct nx842_crypto_header *hdr = &ctx->header;
> + struct nx842_crypto_header *hdr =
> + container_of(&ctx->header,
> + struct nx842_crypto_header, hdr);
> struct nx842_crypto_param p;
> struct nx842_constraints c = *ctx->driver->constraints;
> unsigned int groups, hdrsize, h;
> @@ -490,7 +492,7 @@ int nx842_crypto_decompress(struct crypto_tfm *tfm,
> }
>
> memcpy(&ctx->header, src, hdr_len);
> - hdr = &ctx->header;
> + hdr = container_of(&ctx->header, struct nx842_crypto_header, hdr);
>
> for (n = 0; n < hdr->groups; n++) {
> /* ignore applies to last group */
> diff --git a/drivers/crypto/nx/nx-842.h b/drivers/crypto/nx/nx-842.h
> index 7590bfb24d79..1f42c83d2683 100644
> --- a/drivers/crypto/nx/nx-842.h
> +++ b/drivers/crypto/nx/nx-842.h
> @@ -157,9 +157,12 @@ struct nx842_crypto_header_group {
> } __packed;
>
> struct nx842_crypto_header {
> - __be16 magic; /* NX842_CRYPTO_MAGIC */
> - __be16 ignore; /* decompressed end bytes to ignore */
> - u8 groups; /* total groups in this header */
> + /* New members must be added within the __struct_group() macro below. */
> + __struct_group(nx842_crypto_header_hdr, hdr, __packed,
> + __be16 magic; /* NX842_CRYPTO_MAGIC */
> + __be16 ignore; /* decompressed end bytes to ignore */
> + u8 groups; /* total groups in this header */
> + );
> struct nx842_crypto_header_group group[];
> } __packed;
>
> @@ -171,7 +174,7 @@ struct nx842_crypto_ctx {
> u8 *wmem;
> u8 *sbounce, *dbounce;
>
> - struct nx842_crypto_header header;
> + struct nx842_crypto_header_hdr header;
> struct nx842_crypto_header_group group[NX842_CRYPTO_GROUP_MAX];
>
> struct nx842_driver *driver;
Hmm. I think commit 03952d980153 ("crypto: nx - make platform drivers
directly register with crypto") incorrectly added "struct nx842_driver
*driver" to the end of struct nx842_crypto_ctx. I think it should be
before "header".
Then I see:
#define NX842_CRYPTO_HEADER_SIZE(g) \
(sizeof(struct nx842_crypto_header) + \
sizeof(struct nx842_crypto_header_group) * (g))
This is just struct_size(), really. And nothing uses:
#define NX842_CRYPTO_HEADER_MAX_SIZE \
NX842_CRYPTO_HEADER_SIZE(NX842_CRYPTO_GROUP_MAX)
And then looking for what uses struct nx842_crypto_ctx's "group" member,
I don't see anything except some sizeof()s:
drivers/crypto/nx/nx-common-powernv.c:1044: .cra_ctxsize = sizeof(struct nx842_crypto_ctx),
drivers/crypto/nx/nx-common-pseries.c:1021: .cra_ctxsize = sizeof(struct nx842_crypto_ctx),
This is just a maximally sized ctx (as if the group count were
NX842_CRYPTO_GROUP_MAX), which we could use struct_size for again:
.cra_ctxsize = struct_size_t(struct nx842_crypto_ctx, header.group,
NX842_CRYPTO_GROUP_MAX),
So then "group" can be entirely removed from struct nx842_crypto_ctx.
The result means we can also add __counted_by:
diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c
index 2ab90ec10e61..144972fe2e6f 100644
--- a/drivers/crypto/nx/nx-842.c
+++ b/drivers/crypto/nx/nx-842.c
@@ -62,10 +62,7 @@
*/
#define NX842_CRYPTO_MAGIC (0xf842)
#define NX842_CRYPTO_HEADER_SIZE(g) \
- (sizeof(struct nx842_crypto_header) + \
- sizeof(struct nx842_crypto_header_group) * (g))
-#define NX842_CRYPTO_HEADER_MAX_SIZE \
- NX842_CRYPTO_HEADER_SIZE(NX842_CRYPTO_GROUP_MAX)
+ struct_size_t(nx842_crypto_header, group, g)
/* bounce buffer size */
#define BOUNCE_BUFFER_ORDER (2)
diff --git a/drivers/crypto/nx/nx-842.h b/drivers/crypto/nx/nx-842.h
index 7590bfb24d79..70d9f99a4595 100644
--- a/drivers/crypto/nx/nx-842.h
+++ b/drivers/crypto/nx/nx-842.h
@@ -160,7 +160,7 @@ struct nx842_crypto_header {
__be16 magic; /* NX842_CRYPTO_MAGIC */
__be16 ignore; /* decompressed end bytes to ignore */
u8 groups; /* total groups in this header */
- struct nx842_crypto_header_group group[];
+ struct nx842_crypto_header_group group[] __counted_by(groups);
} __packed;
#define NX842_CRYPTO_GROUP_MAX (0x20)
@@ -171,10 +171,9 @@ struct nx842_crypto_ctx {
u8 *wmem;
u8 *sbounce, *dbounce;
- struct nx842_crypto_header header;
- struct nx842_crypto_header_group group[NX842_CRYPTO_GROUP_MAX];
-
struct nx842_driver *driver;
+
+ struct nx842_crypto_header header;
};
int nx842_crypto_init(struct crypto_tfm *tfm, struct nx842_driver *driver);
diff --git a/drivers/crypto/nx/nx-common-powernv.c b/drivers/crypto/nx/nx-common-powernv.c
index 8c859872c183..22ab4a5885f2 100644
--- a/drivers/crypto/nx/nx-common-powernv.c
+++ b/drivers/crypto/nx/nx-common-powernv.c
@@ -1041,7 +1041,8 @@ static struct crypto_alg nx842_powernv_alg = {
.cra_driver_name = "842-nx",
.cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
- .cra_ctxsize = sizeof(struct nx842_crypto_ctx),
+ .cra_ctxsize = struct_size_t(struct nx842_crypto_ctx, header.group,
+ NX842_CRYPTO_GROUP_MAX),
.cra_module = THIS_MODULE,
.cra_init = nx842_powernv_crypto_init,
.cra_exit = nx842_crypto_exit,
diff --git a/drivers/crypto/nx/nx-common-pseries.c b/drivers/crypto/nx/nx-common-pseries.c
index 35f2d0d8507e..fdf328eab6fc 100644
--- a/drivers/crypto/nx/nx-common-pseries.c
+++ b/drivers/crypto/nx/nx-common-pseries.c
@@ -1018,7 +1018,8 @@ static struct crypto_alg nx842_pseries_alg = {
.cra_driver_name = "842-nx",
.cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
- .cra_ctxsize = sizeof(struct nx842_crypto_ctx),
+ .cra_ctxsize = struct_size_t(struct nx842_crypto_ctx, header.group,
+ NX842_CRYPTO_GROUP_MAX),
.cra_module = THIS_MODULE,
.cra_init = nx842_pseries_crypto_init,
.cra_exit = nx842_crypto_exit,
--
Kees Cook
WARNING: multiple messages have this Message-ID (diff)
From: Kees Cook <keescook@chromium.org>
To: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: Herbert Xu <herbert@gondor.apana.org.au>,
Nicholas Piggin <npiggin@gmail.com>,
linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org,
"Aneesh Kumar K.V" <aneesh.kumar@kernel.org>,
"Naveen N. Rao" <naveen.n.rao@linux.ibm.com>,
linuxppc-dev@lists.ozlabs.org,
"David S. Miller" <davem@davemloft.net>,
linux-hardening@vger.kernel.org
Subject: Re: [PATCH][next] crypto/nx: Avoid potential -Wflex-array-member-not-at-end warning
Date: Mon, 29 Apr 2024 10:05:01 -0700 [thread overview]
Message-ID: <202404290947.4A8BF6A6@keescook> (raw)
In-Reply-To: <ZgHmRNcR+a4EJX94@neat>
On Mon, Mar 25, 2024 at 03:01:56PM -0600, Gustavo A. R. Silva wrote:
> -Wflex-array-member-not-at-end is coming in GCC-14, and we are getting
> ready to enable it globally.
>
> Use the `__struct_group()` helper to separate the flexible array
> from the rest of the members in flexible `struct nx842_crypto_header`,
> through tagged `struct nx842_crypto_header_hdr`, and avoid embedding
> the flexible-array member in the middle of `struct nx842_crypto_ctx`.
>
> Also, use `container_of()` whenever we need to retrieve a pointer to
> the flexible structure.
>
> This code was detected with the help of Coccinelle, and audited and
> modified manually.
>
> Link: https://github.com/KSPP/linux/issues/202
> Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> ---
> drivers/crypto/nx/nx-842.c | 6 ++++--
> drivers/crypto/nx/nx-842.h | 11 +++++++----
> 2 files changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c
> index 2ab90ec10e61..82214cde2bcd 100644
> --- a/drivers/crypto/nx/nx-842.c
> +++ b/drivers/crypto/nx/nx-842.c
> @@ -251,7 +251,9 @@ int nx842_crypto_compress(struct crypto_tfm *tfm,
> u8 *dst, unsigned int *dlen)
> {
> struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
> - struct nx842_crypto_header *hdr = &ctx->header;
> + struct nx842_crypto_header *hdr =
> + container_of(&ctx->header,
> + struct nx842_crypto_header, hdr);
> struct nx842_crypto_param p;
> struct nx842_constraints c = *ctx->driver->constraints;
> unsigned int groups, hdrsize, h;
> @@ -490,7 +492,7 @@ int nx842_crypto_decompress(struct crypto_tfm *tfm,
> }
>
> memcpy(&ctx->header, src, hdr_len);
> - hdr = &ctx->header;
> + hdr = container_of(&ctx->header, struct nx842_crypto_header, hdr);
>
> for (n = 0; n < hdr->groups; n++) {
> /* ignore applies to last group */
> diff --git a/drivers/crypto/nx/nx-842.h b/drivers/crypto/nx/nx-842.h
> index 7590bfb24d79..1f42c83d2683 100644
> --- a/drivers/crypto/nx/nx-842.h
> +++ b/drivers/crypto/nx/nx-842.h
> @@ -157,9 +157,12 @@ struct nx842_crypto_header_group {
> } __packed;
>
> struct nx842_crypto_header {
> - __be16 magic; /* NX842_CRYPTO_MAGIC */
> - __be16 ignore; /* decompressed end bytes to ignore */
> - u8 groups; /* total groups in this header */
> + /* New members must be added within the __struct_group() macro below. */
> + __struct_group(nx842_crypto_header_hdr, hdr, __packed,
> + __be16 magic; /* NX842_CRYPTO_MAGIC */
> + __be16 ignore; /* decompressed end bytes to ignore */
> + u8 groups; /* total groups in this header */
> + );
> struct nx842_crypto_header_group group[];
> } __packed;
>
> @@ -171,7 +174,7 @@ struct nx842_crypto_ctx {
> u8 *wmem;
> u8 *sbounce, *dbounce;
>
> - struct nx842_crypto_header header;
> + struct nx842_crypto_header_hdr header;
> struct nx842_crypto_header_group group[NX842_CRYPTO_GROUP_MAX];
>
> struct nx842_driver *driver;
Hmm. I think commit 03952d980153 ("crypto: nx - make platform drivers
directly register with crypto") incorrectly added "struct nx842_driver
*driver" to the end of struct nx842_crypto_ctx. I think it should be
before "header".
Then I see:
#define NX842_CRYPTO_HEADER_SIZE(g) \
(sizeof(struct nx842_crypto_header) + \
sizeof(struct nx842_crypto_header_group) * (g))
This is just struct_size(), really. And nothing uses:
#define NX842_CRYPTO_HEADER_MAX_SIZE \
NX842_CRYPTO_HEADER_SIZE(NX842_CRYPTO_GROUP_MAX)
And then looking for what uses struct nx842_crypto_ctx's "group" member,
I don't see anything except some sizeof()s:
drivers/crypto/nx/nx-common-powernv.c:1044: .cra_ctxsize = sizeof(struct nx842_crypto_ctx),
drivers/crypto/nx/nx-common-pseries.c:1021: .cra_ctxsize = sizeof(struct nx842_crypto_ctx),
This is just a maximally sized ctx (as if the group count were
NX842_CRYPTO_GROUP_MAX), which we could use struct_size for again:
.cra_ctxsize = struct_size_t(struct nx842_crypto_ctx, header.group,
NX842_CRYPTO_GROUP_MAX),
So then "group" can be entirely removed from struct nx842_crypto_ctx.
The result means we can also add __counted_by:
diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c
index 2ab90ec10e61..144972fe2e6f 100644
--- a/drivers/crypto/nx/nx-842.c
+++ b/drivers/crypto/nx/nx-842.c
@@ -62,10 +62,7 @@
*/
#define NX842_CRYPTO_MAGIC (0xf842)
#define NX842_CRYPTO_HEADER_SIZE(g) \
- (sizeof(struct nx842_crypto_header) + \
- sizeof(struct nx842_crypto_header_group) * (g))
-#define NX842_CRYPTO_HEADER_MAX_SIZE \
- NX842_CRYPTO_HEADER_SIZE(NX842_CRYPTO_GROUP_MAX)
+ struct_size_t(nx842_crypto_header, group, g)
/* bounce buffer size */
#define BOUNCE_BUFFER_ORDER (2)
diff --git a/drivers/crypto/nx/nx-842.h b/drivers/crypto/nx/nx-842.h
index 7590bfb24d79..70d9f99a4595 100644
--- a/drivers/crypto/nx/nx-842.h
+++ b/drivers/crypto/nx/nx-842.h
@@ -160,7 +160,7 @@ struct nx842_crypto_header {
__be16 magic; /* NX842_CRYPTO_MAGIC */
__be16 ignore; /* decompressed end bytes to ignore */
u8 groups; /* total groups in this header */
- struct nx842_crypto_header_group group[];
+ struct nx842_crypto_header_group group[] __counted_by(groups);
} __packed;
#define NX842_CRYPTO_GROUP_MAX (0x20)
@@ -171,10 +171,9 @@ struct nx842_crypto_ctx {
u8 *wmem;
u8 *sbounce, *dbounce;
- struct nx842_crypto_header header;
- struct nx842_crypto_header_group group[NX842_CRYPTO_GROUP_MAX];
-
struct nx842_driver *driver;
+
+ struct nx842_crypto_header header;
};
int nx842_crypto_init(struct crypto_tfm *tfm, struct nx842_driver *driver);
diff --git a/drivers/crypto/nx/nx-common-powernv.c b/drivers/crypto/nx/nx-common-powernv.c
index 8c859872c183..22ab4a5885f2 100644
--- a/drivers/crypto/nx/nx-common-powernv.c
+++ b/drivers/crypto/nx/nx-common-powernv.c
@@ -1041,7 +1041,8 @@ static struct crypto_alg nx842_powernv_alg = {
.cra_driver_name = "842-nx",
.cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
- .cra_ctxsize = sizeof(struct nx842_crypto_ctx),
+ .cra_ctxsize = struct_size_t(struct nx842_crypto_ctx, header.group,
+ NX842_CRYPTO_GROUP_MAX),
.cra_module = THIS_MODULE,
.cra_init = nx842_powernv_crypto_init,
.cra_exit = nx842_crypto_exit,
diff --git a/drivers/crypto/nx/nx-common-pseries.c b/drivers/crypto/nx/nx-common-pseries.c
index 35f2d0d8507e..fdf328eab6fc 100644
--- a/drivers/crypto/nx/nx-common-pseries.c
+++ b/drivers/crypto/nx/nx-common-pseries.c
@@ -1018,7 +1018,8 @@ static struct crypto_alg nx842_pseries_alg = {
.cra_driver_name = "842-nx",
.cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
- .cra_ctxsize = sizeof(struct nx842_crypto_ctx),
+ .cra_ctxsize = struct_size_t(struct nx842_crypto_ctx, header.group,
+ NX842_CRYPTO_GROUP_MAX),
.cra_module = THIS_MODULE,
.cra_init = nx842_pseries_crypto_init,
.cra_exit = nx842_crypto_exit,
--
Kees Cook
next prev parent reply other threads:[~2024-04-29 17:05 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-25 21:01 [PATCH][next] crypto/nx: Avoid potential -Wflex-array-member-not-at-end warning Gustavo A. R. Silva
2024-03-25 21:01 ` Gustavo A. R. Silva
2024-04-29 17:05 ` Kees Cook [this message]
2024-04-29 17:05 ` Kees Cook
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=202404290947.4A8BF6A6@keescook \
--to=keescook@chromium.org \
--cc=aneesh.kumar@kernel.org \
--cc=christophe.leroy@csgroup.eu \
--cc=davem@davemloft.net \
--cc=gustavoars@kernel.org \
--cc=haren@us.ibm.com \
--cc=herbert@gondor.apana.org.au \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=mpe@ellerman.id.au \
--cc=naveen.n.rao@linux.ibm.com \
--cc=npiggin@gmail.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.