* [PATCH libcrypto v4 1/3] wifi: iwlwifi: trans: rename at_least variable to min_mode
@ 2025-11-23 5:48 Jason A. Donenfeld
2025-11-23 5:48 ` [PATCH libcrypto v4 2/3] compiler: introduce at_least parameter decoration pseudo keyword Jason A. Donenfeld
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Jason A. Donenfeld @ 2025-11-23 5:48 UTC (permalink / raw)
To: Linus Torvalds, Eric Biggers, Ard Biesheuvel, Kees Cook,
linux-crypto, linux-kernel
Cc: Jason A. Donenfeld, Miri Korenblit
The subsequent commit is going to add a macro that redefines `at_least`
to mean something else. Given that the usage here in iwlwifi is the only
use of that identifier in the whole kernel, just rename it to a more
fitting name, `min_mode`.
Cc: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
drivers/net/wireless/intel/iwlwifi/iwl-trans.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
index 5232f66c2d52..cc8a84018f70 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
@@ -129,7 +129,7 @@ static enum iwl_reset_mode
iwl_trans_determine_restart_mode(struct iwl_trans *trans)
{
struct iwl_trans_dev_restart_data *data;
- enum iwl_reset_mode at_least = 0;
+ enum iwl_reset_mode min_mode = 0;
unsigned int index;
static const enum iwl_reset_mode escalation_list_old[] = {
IWL_RESET_MODE_SW_RESET,
@@ -173,11 +173,11 @@ iwl_trans_determine_restart_mode(struct iwl_trans *trans)
}
if (trans->restart.during_reset)
- at_least = IWL_RESET_MODE_REPROBE;
+ min_mode = IWL_RESET_MODE_REPROBE;
data = iwl_trans_get_restart_data(trans->dev);
if (!data)
- return at_least;
+ return min_mode;
if (!data->backoff &&
ktime_get_boottime_seconds() - data->last_error >=
@@ -194,7 +194,7 @@ iwl_trans_determine_restart_mode(struct iwl_trans *trans)
data->backoff = false;
}
- return max(at_least, escalation_list[index]);
+ return max(min_mode, escalation_list[index]);
}
#define IWL_TRANS_TOP_FOLLOWER_WAIT 180 /* ms */
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH libcrypto v4 2/3] compiler: introduce at_least parameter decoration pseudo keyword
2025-11-23 5:48 [PATCH libcrypto v4 1/3] wifi: iwlwifi: trans: rename at_least variable to min_mode Jason A. Donenfeld
@ 2025-11-23 5:48 ` Jason A. Donenfeld
2025-11-23 5:53 ` Jason A. Donenfeld
2025-11-23 5:48 ` [PATCH libcrypto v4 3/3] crypto: chacha20poly1305: statically check fixed array lengths Jason A. Donenfeld
2025-11-23 20:28 ` [PATCH libcrypto v4 1/3] wifi: iwlwifi: trans: rename at_least variable to min_mode Eric Biggers
2 siblings, 1 reply; 5+ messages in thread
From: Jason A. Donenfeld @ 2025-11-23 5:48 UTC (permalink / raw)
To: Linus Torvalds, Eric Biggers, Ard Biesheuvel, Kees Cook,
linux-crypto, linux-kernel
Cc: Jason A. Donenfeld
Clang and recent gcc support warning if they are able to prove that the
user is passing to a function an array that is too short in size. For
example:
void blah(unsigned char herp[at_least 7]);
static void schma(void)
{
unsigned char good[] = { 1, 2, 3, 4, 5, 6, 7 };
unsigned char bad[] = { 1, 2, 3, 4, 5, 6 };
blah(good);
blah(bad);
}
The notation here, `static 7`, which this commit makes explicit by
allowing us to write it as `at_least 7`, means that it's incorrect to
pass anything less than 7 elements. This is section 6.7.5.3 of C99:
If the keyword static also appears within the [ and ] of the array
type derivation, then for each call to the function, the value of
the corresponding actual argument shall provide access to the first
element of an array with at least as many elements as specified by
the size expression.
Here is the output from gcc 15:
zx2c4@thinkpad /tmp $ gcc -c a.c
a.c: In function ‘schma’:
a.c:9:9: warning: ‘blah’ accessing 7 bytes in a region of size 6 [-Wstringop-overflow=]
9 | blah(bad);
| ^~~~~~~~~
a.c:9:9: note: referencing argument 1 of type ‘unsigned char[7]’
a.c:2:6: note: in a call to function ‘blah’
2 | void blah(unsigned char herp[at_least 7]);
| ^~~~
And from clang 21:
zx2c4@thinkpad /tmp $ clang -c a.c
a.c:9:2: warning: array argument is too small; contains 6 elements, callee requires at least 7
[-Warray-bounds]
9 | blah(bad);
| ^ ~~~
a.c:2:25: note: callee declares array parameter as static here
2 | void blah(unsigned char herp[at_least 7]);
| ^ ~~~~~~~~~~
1 warning generated.
So these are covered by, variously, -Wstringop-overflow and
-Warray-bounds.
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
Changes v3->v4:
- Move to compiler_types.h
include/linux/compiler_types.h | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index 59288a2c1ad2..51f0dccdb54d 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -394,6 +394,21 @@ struct ftrace_likely_data {
#define __counted_by_be(member) __counted_by(member)
#endif
+/*
+ * This designates the minimum number of elements a passed array parameter must
+ * have. For example:
+ *
+ * void some_function(u8 param[at_least 7]);
+ *
+ * If a caller passes an array with fewer than 7 elements, the compiler will
+ * emit a warning.
+ */
+#ifndef __CHECKER__
+#define at_least static
+#else
+#define at_least
+#endif
+
/* Do not trap wrapping arithmetic within an annotated function. */
#ifdef CONFIG_UBSAN_INTEGER_WRAP
# define __signed_wrap __attribute__((no_sanitize("signed-integer-overflow")))
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH libcrypto v4 3/3] crypto: chacha20poly1305: statically check fixed array lengths
2025-11-23 5:48 [PATCH libcrypto v4 1/3] wifi: iwlwifi: trans: rename at_least variable to min_mode Jason A. Donenfeld
2025-11-23 5:48 ` [PATCH libcrypto v4 2/3] compiler: introduce at_least parameter decoration pseudo keyword Jason A. Donenfeld
@ 2025-11-23 5:48 ` Jason A. Donenfeld
2025-11-23 20:28 ` [PATCH libcrypto v4 1/3] wifi: iwlwifi: trans: rename at_least variable to min_mode Eric Biggers
2 siblings, 0 replies; 5+ messages in thread
From: Jason A. Donenfeld @ 2025-11-23 5:48 UTC (permalink / raw)
To: Linus Torvalds, Eric Biggers, Ard Biesheuvel, Kees Cook,
linux-crypto, linux-kernel
Cc: Jason A. Donenfeld
Several parameters of the chacha20poly1305 functions require arrays of
an exact length. Use the new at_least keyword to instruct gcc and
clang to statically check that the caller is passing an object of at
least that length.
Here it is in action, with this faulty patch to wireguard's cookie.h:
struct cookie_checker {
u8 secret[NOISE_HASH_LEN];
- u8 cookie_encryption_key[NOISE_SYMMETRIC_KEY_LEN];
+ u8 cookie_encryption_key[NOISE_SYMMETRIC_KEY_LEN - 1];
u8 message_mac1_key[NOISE_SYMMETRIC_KEY_LEN];
If I try compiling this code, I get this helpful warning:
CC drivers/net/wireguard/cookie.o
drivers/net/wireguard/cookie.c: In function ‘wg_cookie_message_create’:
drivers/net/wireguard/cookie.c:193:9: warning: ‘xchacha20poly1305_encrypt’ reading 32 bytes from a region of size 31 [-Wstringop-overread]
193 | xchacha20poly1305_encrypt(dst->encrypted_cookie, cookie, COOKIE_LEN,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
194 | macs->mac1, COOKIE_LEN, dst->nonce,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
195 | checker->cookie_encryption_key);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireguard/cookie.c:193:9: note: referencing argument 7 of type ‘const u8 *’ {aka ‘const unsigned char *’}
In file included from drivers/net/wireguard/messages.h:10,
from drivers/net/wireguard/cookie.h:9,
from drivers/net/wireguard/cookie.c:6:
include/crypto/chacha20poly1305.h:28:6: note: in a call to function ‘xchacha20poly1305_encrypt’
28 | void xchacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len,
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
include/crypto/chacha20poly1305.h | 16 ++++++++--------
lib/crypto/chacha20poly1305.c | 18 +++++++++---------
2 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/include/crypto/chacha20poly1305.h b/include/crypto/chacha20poly1305.h
index d2ac3ff7dc1e..7617366f8218 100644
--- a/include/crypto/chacha20poly1305.h
+++ b/include/crypto/chacha20poly1305.h
@@ -18,32 +18,32 @@ enum chacha20poly1305_lengths {
void chacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len,
const u8 *ad, const size_t ad_len,
const u64 nonce,
- const u8 key[CHACHA20POLY1305_KEY_SIZE]);
+ const u8 key[at_least CHACHA20POLY1305_KEY_SIZE]);
bool __must_check
chacha20poly1305_decrypt(u8 *dst, const u8 *src, const size_t src_len,
const u8 *ad, const size_t ad_len, const u64 nonce,
- const u8 key[CHACHA20POLY1305_KEY_SIZE]);
+ const u8 key[at_least CHACHA20POLY1305_KEY_SIZE]);
void xchacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len,
const u8 *ad, const size_t ad_len,
- const u8 nonce[XCHACHA20POLY1305_NONCE_SIZE],
- const u8 key[CHACHA20POLY1305_KEY_SIZE]);
+ const u8 nonce[at_least XCHACHA20POLY1305_NONCE_SIZE],
+ const u8 key[at_least CHACHA20POLY1305_KEY_SIZE]);
bool __must_check xchacha20poly1305_decrypt(
u8 *dst, const u8 *src, const size_t src_len, const u8 *ad,
- const size_t ad_len, const u8 nonce[XCHACHA20POLY1305_NONCE_SIZE],
- const u8 key[CHACHA20POLY1305_KEY_SIZE]);
+ const size_t ad_len, const u8 nonce[at_least XCHACHA20POLY1305_NONCE_SIZE],
+ const u8 key[at_least CHACHA20POLY1305_KEY_SIZE]);
bool chacha20poly1305_encrypt_sg_inplace(struct scatterlist *src, size_t src_len,
const u8 *ad, const size_t ad_len,
const u64 nonce,
- const u8 key[CHACHA20POLY1305_KEY_SIZE]);
+ const u8 key[at_least CHACHA20POLY1305_KEY_SIZE]);
bool chacha20poly1305_decrypt_sg_inplace(struct scatterlist *src, size_t src_len,
const u8 *ad, const size_t ad_len,
const u64 nonce,
- const u8 key[CHACHA20POLY1305_KEY_SIZE]);
+ const u8 key[at_least CHACHA20POLY1305_KEY_SIZE]);
bool chacha20poly1305_selftest(void);
diff --git a/lib/crypto/chacha20poly1305.c b/lib/crypto/chacha20poly1305.c
index 0b49d6aedefd..212ce33562af 100644
--- a/lib/crypto/chacha20poly1305.c
+++ b/lib/crypto/chacha20poly1305.c
@@ -89,7 +89,7 @@ __chacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len,
void chacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len,
const u8 *ad, const size_t ad_len,
const u64 nonce,
- const u8 key[CHACHA20POLY1305_KEY_SIZE])
+ const u8 key[at_least CHACHA20POLY1305_KEY_SIZE])
{
struct chacha_state chacha_state;
u32 k[CHACHA_KEY_WORDS];
@@ -111,8 +111,8 @@ EXPORT_SYMBOL(chacha20poly1305_encrypt);
void xchacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len,
const u8 *ad, const size_t ad_len,
- const u8 nonce[XCHACHA20POLY1305_NONCE_SIZE],
- const u8 key[CHACHA20POLY1305_KEY_SIZE])
+ const u8 nonce[at_least XCHACHA20POLY1305_NONCE_SIZE],
+ const u8 key[at_least CHACHA20POLY1305_KEY_SIZE])
{
struct chacha_state chacha_state;
@@ -170,7 +170,7 @@ __chacha20poly1305_decrypt(u8 *dst, const u8 *src, const size_t src_len,
bool chacha20poly1305_decrypt(u8 *dst, const u8 *src, const size_t src_len,
const u8 *ad, const size_t ad_len,
const u64 nonce,
- const u8 key[CHACHA20POLY1305_KEY_SIZE])
+ const u8 key[at_least CHACHA20POLY1305_KEY_SIZE])
{
struct chacha_state chacha_state;
u32 k[CHACHA_KEY_WORDS];
@@ -195,8 +195,8 @@ EXPORT_SYMBOL(chacha20poly1305_decrypt);
bool xchacha20poly1305_decrypt(u8 *dst, const u8 *src, const size_t src_len,
const u8 *ad, const size_t ad_len,
- const u8 nonce[XCHACHA20POLY1305_NONCE_SIZE],
- const u8 key[CHACHA20POLY1305_KEY_SIZE])
+ const u8 nonce[at_least XCHACHA20POLY1305_NONCE_SIZE],
+ const u8 key[at_least CHACHA20POLY1305_KEY_SIZE])
{
struct chacha_state chacha_state;
@@ -211,7 +211,7 @@ bool chacha20poly1305_crypt_sg_inplace(struct scatterlist *src,
const size_t src_len,
const u8 *ad, const size_t ad_len,
const u64 nonce,
- const u8 key[CHACHA20POLY1305_KEY_SIZE],
+ const u8 key[at_least CHACHA20POLY1305_KEY_SIZE],
int encrypt)
{
const u8 *pad0 = page_address(ZERO_PAGE(0));
@@ -335,7 +335,7 @@ bool chacha20poly1305_crypt_sg_inplace(struct scatterlist *src,
bool chacha20poly1305_encrypt_sg_inplace(struct scatterlist *src, size_t src_len,
const u8 *ad, const size_t ad_len,
const u64 nonce,
- const u8 key[CHACHA20POLY1305_KEY_SIZE])
+ const u8 key[at_least CHACHA20POLY1305_KEY_SIZE])
{
return chacha20poly1305_crypt_sg_inplace(src, src_len, ad, ad_len,
nonce, key, 1);
@@ -345,7 +345,7 @@ EXPORT_SYMBOL(chacha20poly1305_encrypt_sg_inplace);
bool chacha20poly1305_decrypt_sg_inplace(struct scatterlist *src, size_t src_len,
const u8 *ad, const size_t ad_len,
const u64 nonce,
- const u8 key[CHACHA20POLY1305_KEY_SIZE])
+ const u8 key[at_least CHACHA20POLY1305_KEY_SIZE])
{
if (unlikely(src_len < POLY1305_DIGEST_SIZE))
return false;
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH libcrypto v4 2/3] compiler: introduce at_least parameter decoration pseudo keyword
2025-11-23 5:48 ` [PATCH libcrypto v4 2/3] compiler: introduce at_least parameter decoration pseudo keyword Jason A. Donenfeld
@ 2025-11-23 5:53 ` Jason A. Donenfeld
0 siblings, 0 replies; 5+ messages in thread
From: Jason A. Donenfeld @ 2025-11-23 5:53 UTC (permalink / raw)
To: Linus Torvalds, Eric Biggers, Ard Biesheuvel, Kees Cook,
linux-crypto, linux-kernel
Ah, the subject should probably be "compiler_types: ...".
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH libcrypto v4 1/3] wifi: iwlwifi: trans: rename at_least variable to min_mode
2025-11-23 5:48 [PATCH libcrypto v4 1/3] wifi: iwlwifi: trans: rename at_least variable to min_mode Jason A. Donenfeld
2025-11-23 5:48 ` [PATCH libcrypto v4 2/3] compiler: introduce at_least parameter decoration pseudo keyword Jason A. Donenfeld
2025-11-23 5:48 ` [PATCH libcrypto v4 3/3] crypto: chacha20poly1305: statically check fixed array lengths Jason A. Donenfeld
@ 2025-11-23 20:28 ` Eric Biggers
2 siblings, 0 replies; 5+ messages in thread
From: Eric Biggers @ 2025-11-23 20:28 UTC (permalink / raw)
To: Jason A. Donenfeld
Cc: Linus Torvalds, Ard Biesheuvel, Kees Cook, linux-crypto,
linux-kernel, Miri Korenblit
On Sun, Nov 23, 2025 at 06:48:17AM +0100, Jason A. Donenfeld wrote:
> The subsequent commit is going to add a macro that redefines `at_least`
> to mean something else. Given that the usage here in iwlwifi is the only
> use of that identifier in the whole kernel, just rename it to a more
> fitting name, `min_mode`.
>
> Cc: Miri Korenblit <miriam.rachel.korenblit@intel.com>
> Acked-by: Ard Biesheuvel <ardb@kernel.org>
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> ---
Applied this series to
https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git/log/?h=libcrypto-next
(Again, on a separate branch that I merged in. It will be in its own
pull request)
- Eric
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-11-23 20:30 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-23 5:48 [PATCH libcrypto v4 1/3] wifi: iwlwifi: trans: rename at_least variable to min_mode Jason A. Donenfeld
2025-11-23 5:48 ` [PATCH libcrypto v4 2/3] compiler: introduce at_least parameter decoration pseudo keyword Jason A. Donenfeld
2025-11-23 5:53 ` Jason A. Donenfeld
2025-11-23 5:48 ` [PATCH libcrypto v4 3/3] crypto: chacha20poly1305: statically check fixed array lengths Jason A. Donenfeld
2025-11-23 20:28 ` [PATCH libcrypto v4 1/3] wifi: iwlwifi: trans: rename at_least variable to min_mode Eric Biggers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).