xbc_node_compose_key_after() passes a size_t buffer length to snprintf(), but snprintf() returns int. Guard against size values above INT_MAX before the loop so the existing truncation check can continue to compare ret against (int)size safely.
Add a small WARN_ON_ONCE shim for the tools/bootconfig userspace build so the same source continues to build there. Changes since v2: - Added a comment explaining the INT_MAX guard. Changes since v1: - Removed casting ret to size_t; with the INT_MAX guard, the existing ret >= (int)size check is sufficient, per Steven Rostedt. - Link to v1: https://lore.kernel.org/all/[email protected]/ Signed-off-by: Josh Law <[email protected]> --- lib/bootconfig.c | 8 ++++++++ tools/bootconfig/include/linux/bootconfig.h | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/lib/bootconfig.c b/lib/bootconfig.c index 96cbe6738ffe..2a54b51dec5c 100644 --- a/lib/bootconfig.c +++ b/lib/bootconfig.c @@ -313,6 +313,14 @@ int __init xbc_node_compose_key_after(struct xbc_node *root, if (!node && root) return -EINVAL; + /* + * Bootconfig strings never need multi-GB buffers. Reject sizes + * above INT_MAX so snprintf()'s int return value cannot overflow + * the truncation check below. + */ + if (WARN_ON_ONCE(size > INT_MAX)) + return -EINVAL; + while (--depth >= 0) { node = xbc_nodes + keys[depth]; ret = snprintf(buf, size, "%s%s", xbc_node_get_data(node), diff --git a/tools/bootconfig/include/linux/bootconfig.h b/tools/bootconfig/include/linux/bootconfig.h index 6784296a0692..48383c10e036 100644 --- a/tools/bootconfig/include/linux/bootconfig.h +++ b/tools/bootconfig/include/linux/bootconfig.h @@ -8,6 +8,7 @@ #include <stdbool.h> #include <ctype.h> #include <errno.h> +#include <limits.h> #include <string.h> @@ -19,6 +20,10 @@ ((cond) ? printf("Internal warning(%s:%d, %s): %s\n", \ __FILE__, __LINE__, __func__, #cond) : 0) +#ifndef WARN_ON_ONCE +#define WARN_ON_ONCE(cond) WARN_ON(cond) +#endif + #define unlikely(cond) (cond) /* Copied from lib/string.c */ -- 2.34.1
