* FAILED: patch "[PATCH] tools/bootconfig: Fix integer overflow and truncation in size" failed to apply to 5.10-stable tree
@ 2026-09-16 14:16 gregkh
2026-09-16 19:07 ` [PATCH 5.10.y 1/7] tools/bootconfig: Simplify expression Sasha Levin
0 siblings, 1 reply; 8+ messages in thread
From: gregkh @ 2026-09-16 14:16 UTC (permalink / raw)
To: mhiramat, ekffu200098, sashiko-bot; +Cc: stable
The patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x 462d0b066b613103f579793031429db2ca23abc0
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026091617-cackle-deeply-2ea2@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 462d0b066b613103f579793031429db2ca23abc0 Mon Sep 17 00:00:00 2001
From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
Date: Fri, 11 Sep 2026 00:15:24 +0900
Subject: [PATCH] tools/bootconfig: Fix integer overflow and truncation in size
checks
Sashiko reported that on 32-bit systems, if an attacker crafts size in
the bootconfig footer such that adding BOOTCONFIG_FOOTER_SIZE wraps around
(for instance, if size is 0xFFFFFFFF), the size check in
load_xbc_from_initrd() can be bypassed:
if (stat.st_size < size + BOOTCONFIG_FOOTER_SIZE) {
pr_err("bootconfig size is too big\n");
return -E2BIG;
}
Furthermore, on 64-bit systems with an initrd > 4.29 GB, comparing a
corrupted 32-bit size (e.g. 0xFFFFFFFF) against
stat.st_size - BOOTCONFIG_FOOTER_SIZE can also bypass the check if
size is not bounded. Similarly, load_xbc_file() passes 64-bit stat.st_size
directly into the 32-bit int size parameter of load_xbc_fd(), truncating
large standalone files (>= 2GB).
In both cases, passing 0xFFFFFFFF to load_xbc_fd() truncates to -1,
resulting in malloc(0), an integer overflow in read(), and an
out-of-bounds null-byte write.
Fix this by:
1. Rejecting size > XBC_DATA_MAX or
size > stat.st_size - BOOTCONFIG_FOOTER_SIZE in load_xbc_from_initrd().
2. Rejecting stat.st_size > XBC_DATA_MAX in load_xbc_file() before passing
it to load_xbc_fd().
3. Checking size < 0 || size > XBC_DATA_MAX defensively in load_xbc_fd().
Link: https://lore.kernel.org/all/178905332413.213925.3179977110281463499.stgit@devnote2/
Fixes: 950313ebf79c ("tools: bootconfig: Add bootconfig command")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260909161113.16C691F00A3A@smtp.kernel.org/
Closes: https://lore.kernel.org/all/20260910010137.EE0431F000FF@smtp.kernel.org/
Assisted-by: Antigravity:gemini-3.8-flash
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Sang-Heon Jeon <ekffu200098@gmail.com>
diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c
index 7dc9fff9b637..17d971d47f87 100644
--- a/tools/bootconfig/main.c
+++ b/tools/bootconfig/main.c
@@ -140,6 +140,9 @@ static int load_xbc_fd(int fd, char **buf, int size)
{
int ret;
+ if (size < 0 || size > XBC_DATA_MAX)
+ return -EINVAL;
+
*buf = malloc(size + 1);
if (!*buf)
return -ENOMEM;
@@ -168,6 +171,13 @@ static int load_xbc_file(const char *path, char **buf)
return ret;
}
+ if (stat.st_size > XBC_DATA_MAX) {
+ pr_err("%s size is too big\n", path);
+ ret = -E2BIG;
+ close(fd);
+ return ret;
+ }
+
ret = load_xbc_fd(fd, buf, stat.st_size);
close(fd);
@@ -218,7 +228,8 @@ static int load_xbc_from_initrd(int fd, char **buf)
csum = le32toh(csum);
/* Wrong size error */
- if (stat.st_size < size + BOOTCONFIG_FOOTER_SIZE) {
+ if (size > XBC_DATA_MAX ||
+ size > stat.st_size - BOOTCONFIG_FOOTER_SIZE) {
pr_err("bootconfig size is too big\n");
return -E2BIG;
}
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5.10.y 1/7] tools/bootconfig: Simplify expression
2026-09-16 14:16 FAILED: patch "[PATCH] tools/bootconfig: Fix integer overflow and truncation in size" failed to apply to 5.10-stable tree gregkh
@ 2026-09-16 19:07 ` Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 2/7] bootconfig: Change array value to use child node Sasha Levin
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: Sasha Levin @ 2026-09-16 19:07 UTC (permalink / raw)
To: stable; +Cc: zuoqilin, Masami Hiramatsu, Steven Rostedt (VMware), Sasha Levin
From: zuoqilin <zuoqilin@yulong.com>
[ Upstream commit 30d103f2d4602da07313cf43d7b746e89d7d9c1d ]
It is not necessary to define the variable ret to receive
the return value of the xbc_node_compose_key() method.
Link: https://lkml.kernel.org/r/20210414134647.1870-1-zuoqilin1@163.com
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: zuoqilin <zuoqilin@yulong.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Stable-dep-of: 462d0b066b61 ("tools/bootconfig: Fix integer overflow and truncation in size checks")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/bootconfig/main.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c
index 387cb91862dfc..6862afd66cfd3 100644
--- a/tools/bootconfig/main.c
+++ b/tools/bootconfig/main.c
@@ -84,11 +84,9 @@ static void xbc_show_list(void)
char key[XBC_KEYLEN_MAX];
struct xbc_node *leaf;
const char *val;
- int ret = 0;
xbc_for_each_key_value(leaf, val) {
- ret = xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX);
- if (ret < 0)
+ if (xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX) < 0)
break;
printf("%s = ", key);
if (!val || val[0] == '\0') {
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5.10.y 2/7] bootconfig: Change array value to use child node
2026-09-16 19:07 ` [PATCH 5.10.y 1/7] tools/bootconfig: Simplify expression Sasha Levin
@ 2026-09-16 19:07 ` Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 3/7] bootconfig: Share the checksum function with tools Sasha Levin
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2026-09-16 19:07 UTC (permalink / raw)
To: stable; +Cc: Masami Hiramatsu, Steven Rostedt (VMware), Sasha Levin
From: Masami Hiramatsu <mhiramat@kernel.org>
[ Upstream commit ca24306d83a125df187ad53eddb038fe0cffb8ca ]
It is not possible to put an array value with subkeys under
a key node, because both of subkeys and the array elements
are using "next" field of the xbc_node.
Thus this changes the array values to use "child" field in
the array case. The reason why split this change is to
test it easily.
Link: https://lkml.kernel.org/r/162262193838.264090.16044473274501498656.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Stable-dep-of: 462d0b066b61 ("tools/bootconfig: Fix integer overflow and truncation in size checks")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/proc/bootconfig.c | 2 +-
include/linux/bootconfig.h | 6 +++---
lib/bootconfig.c | 23 +++++++++++++++++++----
tools/bootconfig/main.c | 2 +-
4 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/fs/proc/bootconfig.c b/fs/proc/bootconfig.c
index d82dae133243b..2e244ada1f970 100644
--- a/fs/proc/bootconfig.c
+++ b/fs/proc/bootconfig.c
@@ -51,7 +51,7 @@ static int __init copy_xbc_key_value_list(char *dst, size_t size)
else
q = '"';
ret = snprintf(dst, rest(dst, end), "%c%s%c%s",
- q, val, q, vnode->next ? ", " : "\n");
+ q, val, q, xbc_node_is_array(vnode) ? ", " : "\n");
if (ret < 0)
goto out;
dst += ret;
diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h
index 39d2e2468c237..2c5f0b2484caa 100644
--- a/include/linux/bootconfig.h
+++ b/include/linux/bootconfig.h
@@ -71,7 +71,7 @@ static inline __init bool xbc_node_is_key(struct xbc_node *node)
*/
static inline __init bool xbc_node_is_array(struct xbc_node *node)
{
- return xbc_node_is_value(node) && node->next != 0;
+ return xbc_node_is_value(node) && node->child != 0;
}
/**
@@ -140,7 +140,7 @@ static inline struct xbc_node * __init xbc_find_node(const char *key)
*/
#define xbc_array_for_each_value(anode, value) \
for (value = xbc_node_get_data(anode); anode != NULL ; \
- anode = xbc_node_get_next(anode), \
+ anode = xbc_node_get_child(anode), \
value = anode ? xbc_node_get_data(anode) : NULL)
/**
@@ -171,7 +171,7 @@ static inline struct xbc_node * __init xbc_find_node(const char *key)
*/
#define xbc_node_for_each_array_value(node, key, anode, value) \
for (value = xbc_node_find_value(node, key, &anode); value != NULL; \
- anode = xbc_node_get_next(anode), \
+ anode = xbc_node_get_child(anode), \
value = anode ? xbc_node_get_data(anode) : NULL)
/**
diff --git a/lib/bootconfig.c b/lib/bootconfig.c
index f6bede03c6926..36146607912e8 100644
--- a/lib/bootconfig.c
+++ b/lib/bootconfig.c
@@ -432,6 +432,14 @@ static inline __init struct xbc_node *xbc_last_sibling(struct xbc_node *node)
return node;
}
+static inline __init struct xbc_node *xbc_last_child(struct xbc_node *node)
+{
+ while (node->child)
+ node = xbc_node_get_child(node);
+
+ return node;
+}
+
static struct xbc_node * __init xbc_add_sibling(char *data, u32 flag)
{
struct xbc_node *sib, *node = xbc_add_node(data, flag);
@@ -582,17 +590,20 @@ static int __init xbc_parse_array(char **__v)
char *next;
int c = 0;
+ if (last_parent->child)
+ last_parent = xbc_node_get_child(last_parent);
+
do {
c = __xbc_parse_value(__v, &next);
if (c < 0)
return c;
- node = xbc_add_sibling(*__v, XBC_VALUE);
+ node = xbc_add_child(*__v, XBC_VALUE);
if (!node)
return -ENOMEM;
*__v = next;
} while (c == ',');
- node->next = 0;
+ node->child = 0;
return c;
}
@@ -680,8 +691,12 @@ static int __init xbc_parse_kv(char **k, char *v, int op)
if (op == ':' && child) {
xbc_init_node(child, v, XBC_VALUE);
- } else if (!xbc_add_sibling(v, XBC_VALUE))
- return -ENOMEM;
+ } else {
+ if (op == '+' && child)
+ last_parent = xbc_last_child(child);
+ if (!xbc_add_sibling(v, XBC_VALUE))
+ return -ENOMEM;
+ }
if (c == ',') { /* Array */
c = xbc_parse_array(&next);
diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c
index 6862afd66cfd3..b276fb75065e4 100644
--- a/tools/bootconfig/main.c
+++ b/tools/bootconfig/main.c
@@ -27,7 +27,7 @@ static int xbc_show_value(struct xbc_node *node, bool semicolon)
q = '\'';
else
q = '"';
- printf("%c%s%c%s", q, val, q, node->next ? ", " : eol);
+ printf("%c%s%c%s", q, val, q, xbc_node_is_array(node) ? ", " : eol);
i++;
}
return i;
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5.10.y 3/7] bootconfig: Share the checksum function with tools
2026-09-16 19:07 ` [PATCH 5.10.y 1/7] tools/bootconfig: Simplify expression Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 2/7] bootconfig: Change array value to use child node Sasha Levin
@ 2026-09-16 19:07 ` Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 4/7] tools/bootconfig: Print all error message in stderr Sasha Levin
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2026-09-16 19:07 UTC (permalink / raw)
To: stable; +Cc: Masami Hiramatsu, Steven Rostedt (VMware), Sasha Levin
From: Masami Hiramatsu <mhiramat@kernel.org>
[ Upstream commit 99f4f5d62338cab9dcf45735344541574daedd20 ]
Move the checksum calculation function into the header for sharing it
with tools/bootconfig.
Link: https://lkml.kernel.org/r/162262197470.264090.16325743685807878807.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Stable-dep-of: 462d0b066b61 ("tools/bootconfig: Fix integer overflow and truncation in size checks")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/bootconfig.h | 20 ++++++++++++++++++++
init/main.c | 12 +-----------
tools/bootconfig/main.c | 15 ++-------------
3 files changed, 23 insertions(+), 24 deletions(-)
diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h
index 2c5f0b2484caa..47d2116883b15 100644
--- a/include/linux/bootconfig.h
+++ b/include/linux/bootconfig.h
@@ -16,6 +16,26 @@
#define BOOTCONFIG_ALIGN (1 << BOOTCONFIG_ALIGN_SHIFT)
#define BOOTCONFIG_ALIGN_MASK (BOOTCONFIG_ALIGN - 1)
+/**
+ * xbc_calc_checksum() - Calculate checksum of bootconfig
+ * @data: Bootconfig data.
+ * @size: The size of the bootconfig data.
+ *
+ * Calculate the checksum value of the bootconfig data.
+ * The checksum will be used with the BOOTCONFIG_MAGIC and the size for
+ * embedding the bootconfig in the initrd image.
+ */
+static inline __init u32 xbc_calc_checksum(void *data, u32 size)
+{
+ unsigned char *p = data;
+ u32 ret = 0;
+
+ while (size--)
+ ret += *p++;
+
+ return ret;
+}
+
/* XBC tree node */
struct xbc_node {
u16 next;
diff --git a/init/main.c b/init/main.c
index d23d1a8d5393f..fdddffa54361c 100644
--- a/init/main.c
+++ b/init/main.c
@@ -346,16 +346,6 @@ static char * __init xbc_make_cmdline(const char *key)
return new_cmdline;
}
-static u32 boot_config_checksum(unsigned char *p, u32 size)
-{
- u32 ret = 0;
-
- while (size--)
- ret += *p++;
-
- return ret;
-}
-
static int __init bootconfig_params(char *param, char *val,
const char *unused, void *arg)
{
@@ -399,7 +389,7 @@ static void __init setup_boot_config(const char *cmdline)
return;
}
- if (boot_config_checksum((unsigned char *)data, size) != csum) {
+ if (xbc_calc_checksum(data, size) != csum) {
pr_err("bootconfig checksum failed\n");
return;
}
diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c
index b276fb75065e4..6b212e9835e07 100644
--- a/tools/bootconfig/main.c
+++ b/tools/bootconfig/main.c
@@ -97,17 +97,6 @@ static void xbc_show_list(void)
}
}
-/* Simple real checksum */
-static int checksum(unsigned char *buf, int len)
-{
- int i, sum = 0;
-
- for (i = 0; i < len; i++)
- sum += buf[i];
-
- return sum;
-}
-
#define PAGE_SIZE 4096
static int load_xbc_fd(int fd, char **buf, int size)
@@ -206,7 +195,7 @@ static int load_xbc_from_initrd(int fd, char **buf)
return ret;
/* Wrong Checksum */
- rcsum = checksum((unsigned char *)*buf, size);
+ rcsum = xbc_calc_checksum(*buf, size);
if (csum != rcsum) {
pr_err("checksum error: %u != %u\n", csum, rcsum);
return -EINVAL;
@@ -355,7 +344,7 @@ static int apply_xbc(const char *path, const char *xbc_path)
return ret;
}
size = strlen(buf) + 1;
- csum = checksum((unsigned char *)buf, size);
+ csum = xbc_calc_checksum(buf, size);
/* Backup the bootconfig data */
data = calloc(size + BOOTCONFIG_ALIGN +
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5.10.y 4/7] tools/bootconfig: Print all error message in stderr
2026-09-16 19:07 ` [PATCH 5.10.y 1/7] tools/bootconfig: Simplify expression Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 2/7] bootconfig: Change array value to use child node Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 3/7] bootconfig: Share the checksum function with tools Sasha Levin
@ 2026-09-16 19:07 ` Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 5/7] bootconfig: Replace u16 and u32 with uint16_t and uint32_t Sasha Levin
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2026-09-16 19:07 UTC (permalink / raw)
To: stable; +Cc: Masami Hiramatsu, Steven Rostedt (VMware), Sasha Levin
From: Masami Hiramatsu <mhiramat@kernel.org>
[ Upstream commit 160321b2602ff8e42ea77a09f2e3f1b35e3acfaf ]
Print all error message in stderr. This also removes
unneeded tools/bootconfig/include/linux/printk.h.
Link: https://lkml.kernel.org/r/163187298106.2366983.15210300267326257397.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Stable-dep-of: 462d0b066b61 ("tools/bootconfig: Fix integer overflow and truncation in size checks")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/bootconfig/include/linux/kernel.h | 2 --
tools/bootconfig/include/linux/printk.h | 14 --------------
tools/bootconfig/main.c | 2 ++
3 files changed, 2 insertions(+), 16 deletions(-)
delete mode 100644 tools/bootconfig/include/linux/printk.h
diff --git a/tools/bootconfig/include/linux/kernel.h b/tools/bootconfig/include/linux/kernel.h
index 2d93320aa3742..c4854b8e70237 100644
--- a/tools/bootconfig/include/linux/kernel.h
+++ b/tools/bootconfig/include/linux/kernel.h
@@ -5,8 +5,6 @@
#include <stdlib.h>
#include <stdbool.h>
-#include <linux/printk.h>
-
typedef unsigned short u16;
typedef unsigned int u32;
diff --git a/tools/bootconfig/include/linux/printk.h b/tools/bootconfig/include/linux/printk.h
deleted file mode 100644
index 036e667596eb1..0000000000000
--- a/tools/bootconfig/include/linux/printk.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _SKC_LINUX_PRINTK_H
-#define _SKC_LINUX_PRINTK_H
-
-#include <stdio.h>
-
-#define printk(fmt, ...) printf(fmt, ##__VA_ARGS__)
-
-#define pr_err printk
-#define pr_warn printk
-#define pr_info printk
-#define pr_debug printk
-
-#endif
diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c
index 6b212e9835e07..6dd8afb954e48 100644
--- a/tools/bootconfig/main.c
+++ b/tools/bootconfig/main.c
@@ -15,6 +15,8 @@
#include <linux/kernel.h>
#include <linux/bootconfig.h>
+#define pr_err(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
+
static int xbc_show_value(struct xbc_node *node, bool semicolon)
{
const char *val, *eol;
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5.10.y 5/7] bootconfig: Replace u16 and u32 with uint16_t and uint32_t
2026-09-16 19:07 ` [PATCH 5.10.y 1/7] tools/bootconfig: Simplify expression Sasha Levin
` (2 preceding siblings ...)
2026-09-16 19:07 ` [PATCH 5.10.y 4/7] tools/bootconfig: Print all error message in stderr Sasha Levin
@ 2026-09-16 19:07 ` Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 6/7] tools/bootconfig: Cleanup bootconfig footer size calculations Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 7/7] tools/bootconfig: Fix integer overflow and truncation in size checks Sasha Levin
5 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2026-09-16 19:07 UTC (permalink / raw)
To: stable; +Cc: Masami Hiramatsu, Steven Rostedt (VMware), Sasha Levin
From: Masami Hiramatsu <mhiramat@kernel.org>
[ Upstream commit 4f292c4886bfdfc2a7191ef4ff3f7aac69d1cc3f ]
Replace u16 and u32 with uint16_t and uint32_t so
that the tools/bootconfig only needs <stdint.h>.
Link: https://lkml.kernel.org/r/163187298835.2366983.9838262576854319669.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
[Stable backport: Convert the existing 5.10 xbc_add_sibling() and
xbc_add_child() argument types without importing the newer sibling-helper
refactor or adding functions. Retain the stable parser implementation.
Restore the tools-only linux/printk.h shim removed by the preceding
stderr-conversion dependency. The older parser still includes it for
xbc_debug_dump(), and it also supplies the stdio declarations used by
xbc_snprint_cmdline(). Without it the bootconfig tool cannot compile.
Define BOOTCONFIG_FOOTER_SIZE and use it in the initrd size check, taking
only the context needed from 26dda5769509 ("tools/bootconfig: Cleanup
bootconfig footer size calculations"). This lets the size-check fix in
462d0b066b61 apply unchanged; leave its new validation to that commit.]
Stable-dep-of: 462d0b066b61 ("tools/bootconfig: Fix integer overflow and truncation in size checks")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/bootconfig.h | 12 ++++++------
lib/bootconfig.c | 12 ++++++------
tools/bootconfig/include/linux/kernel.h | 4 +---
tools/bootconfig/include/linux/printk.h | 14 +++++++++++++
tools/bootconfig/main.c | 26 ++++++++++++++-----------
5 files changed, 42 insertions(+), 26 deletions(-)
create mode 100644 tools/bootconfig/include/linux/printk.h
diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h
index 47d2116883b15..32940f3c7ad33 100644
--- a/include/linux/bootconfig.h
+++ b/include/linux/bootconfig.h
@@ -25,10 +25,10 @@
* The checksum will be used with the BOOTCONFIG_MAGIC and the size for
* embedding the bootconfig in the initrd image.
*/
-static inline __init u32 xbc_calc_checksum(void *data, u32 size)
+static inline __init uint32_t xbc_calc_checksum(void *data, uint32_t size)
{
unsigned char *p = data;
- u32 ret = 0;
+ uint32_t ret = 0;
while (size--)
ret += *p++;
@@ -38,10 +38,10 @@ static inline __init u32 xbc_calc_checksum(void *data, u32 size)
/* XBC tree node */
struct xbc_node {
- u16 next;
- u16 child;
- u16 parent;
- u16 data;
+ uint16_t next;
+ uint16_t child;
+ uint16_t parent;
+ uint16_t data;
} __attribute__ ((__packed__));
#define XBC_KEY 0
diff --git a/lib/bootconfig.c b/lib/bootconfig.c
index 36146607912e8..26b4c1dc9e04c 100644
--- a/lib/bootconfig.c
+++ b/lib/bootconfig.c
@@ -226,7 +226,7 @@ int __init xbc_node_compose_key_after(struct xbc_node *root,
struct xbc_node *node,
char *buf, size_t size)
{
- u16 keys[XBC_DEPTH_MAX];
+ uint16_t keys[XBC_DEPTH_MAX];
int depth = 0, ret = 0, total = 0;
if (!node || node == root)
@@ -396,21 +396,21 @@ int __init xbc_snprint_cmdline(char *buf, size_t size, struct xbc_node *root)
/* XBC parse and tree build */
-static int __init xbc_init_node(struct xbc_node *node, char *data, u32 flag)
+static int __init xbc_init_node(struct xbc_node *node, char *data, uint32_t flag)
{
unsigned long offset = data - xbc_data;
if (WARN_ON(offset >= XBC_DATA_MAX))
return -EINVAL;
- node->data = (u16)offset | flag;
+ node->data = (uint16_t)offset | flag;
node->child = 0;
node->next = 0;
return 0;
}
-static struct xbc_node * __init xbc_add_node(char *data, u32 flag)
+static struct xbc_node * __init xbc_add_node(char *data, uint32_t flag)
{
struct xbc_node *node;
@@ -440,7 +440,7 @@ static inline __init struct xbc_node *xbc_last_child(struct xbc_node *node)
return node;
}
-static struct xbc_node * __init xbc_add_sibling(char *data, u32 flag)
+static struct xbc_node * __init xbc_add_sibling(char *data, uint32_t flag)
{
struct xbc_node *sib, *node = xbc_add_node(data, flag);
@@ -465,7 +465,7 @@ static struct xbc_node * __init xbc_add_sibling(char *data, u32 flag)
return node;
}
-static inline __init struct xbc_node *xbc_add_child(char *data, u32 flag)
+static inline __init struct xbc_node *xbc_add_child(char *data, uint32_t flag)
{
struct xbc_node *node = xbc_add_sibling(data, flag);
diff --git a/tools/bootconfig/include/linux/kernel.h b/tools/bootconfig/include/linux/kernel.h
index c4854b8e70237..39f306c18dd0c 100644
--- a/tools/bootconfig/include/linux/kernel.h
+++ b/tools/bootconfig/include/linux/kernel.h
@@ -3,11 +3,9 @@
#define _SKC_LINUX_KERNEL_H
#include <stdlib.h>
+#include <stdint.h>
#include <stdbool.h>
-typedef unsigned short u16;
-typedef unsigned int u32;
-
#define unlikely(cond) (cond)
#define __init
diff --git a/tools/bootconfig/include/linux/printk.h b/tools/bootconfig/include/linux/printk.h
new file mode 100644
index 0000000000000..036e667596eb1
--- /dev/null
+++ b/tools/bootconfig/include/linux/printk.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _SKC_LINUX_PRINTK_H
+#define _SKC_LINUX_PRINTK_H
+
+#include <stdio.h>
+
+#define printk(fmt, ...) printf(fmt, ##__VA_ARGS__)
+
+#define pr_err printk
+#define pr_warn printk
+#define pr_info printk
+#define pr_debug printk
+
+#endif
diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c
index 6dd8afb954e48..358c7007dfe8c 100644
--- a/tools/bootconfig/main.c
+++ b/tools/bootconfig/main.c
@@ -17,6 +17,10 @@
#define pr_err(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
+/* Bootconfig footer is [size][csum][BOOTCONFIG_MAGIC]. */
+#define BOOTCONFIG_FOOTER_SIZE \
+ (sizeof(uint32_t) * 2 + BOOTCONFIG_MAGIC_LEN)
+
static int xbc_show_value(struct xbc_node *node, bool semicolon)
{
const char *val, *eol;
@@ -150,7 +154,7 @@ static int load_xbc_from_initrd(int fd, char **buf)
{
struct stat stat;
int ret;
- u32 size = 0, csum = 0, rcsum;
+ uint32_t size = 0, csum = 0, rcsum;
char magic[BOOTCONFIG_MAGIC_LEN];
const char *msg;
@@ -174,16 +178,16 @@ static int load_xbc_from_initrd(int fd, char **buf)
if (lseek(fd, -(8 + BOOTCONFIG_MAGIC_LEN), SEEK_END) < 0)
return pr_errno("Failed to lseek for size", -errno);
- if (read(fd, &size, sizeof(u32)) < 0)
+ if (read(fd, &size, sizeof(uint32_t)) < 0)
return pr_errno("Failed to read size", -errno);
size = le32toh(size);
- if (read(fd, &csum, sizeof(u32)) < 0)
+ if (read(fd, &csum, sizeof(uint32_t)) < 0)
return pr_errno("Failed to read checksum", -errno);
csum = le32toh(csum);
/* Wrong size error */
- if (stat.st_size < size + 8 + BOOTCONFIG_MAGIC_LEN) {
+ if (stat.st_size < size + BOOTCONFIG_FOOTER_SIZE) {
pr_err("bootconfig size is too big\n");
return -E2BIG;
}
@@ -336,7 +340,7 @@ static int apply_xbc(const char *path, const char *xbc_path)
size_t total_size;
struct stat stat;
const char *msg;
- u32 size, csum;
+ uint32_t size, csum;
int pos, pad;
int ret, fd;
@@ -350,7 +354,7 @@ static int apply_xbc(const char *path, const char *xbc_path)
/* Backup the bootconfig data */
data = calloc(size + BOOTCONFIG_ALIGN +
- sizeof(u32) + sizeof(u32) + BOOTCONFIG_MAGIC_LEN, 1);
+ sizeof(uint32_t) + sizeof(uint32_t) + BOOTCONFIG_MAGIC_LEN, 1);
if (!data)
return -ENOMEM;
memcpy(data, buf, size);
@@ -397,17 +401,17 @@ static int apply_xbc(const char *path, const char *xbc_path)
}
/* To align up the total size to BOOTCONFIG_ALIGN, get padding size */
- total_size = stat.st_size + size + sizeof(u32) * 2 + BOOTCONFIG_MAGIC_LEN;
+ total_size = stat.st_size + size + sizeof(uint32_t) * 2 + BOOTCONFIG_MAGIC_LEN;
pad = ((total_size + BOOTCONFIG_ALIGN - 1) & (~BOOTCONFIG_ALIGN_MASK)) - total_size;
size += pad;
/* Add a footer */
p = data + size;
- *(u32 *)p = htole32(size);
- p += sizeof(u32);
+ *(uint32_t *)p = htole32(size);
+ p += sizeof(uint32_t);
- *(u32 *)p = htole32(csum);
- p += sizeof(u32);
+ *(uint32_t *)p = htole32(csum);
+ p += sizeof(uint32_t);
memcpy(p, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN);
p += BOOTCONFIG_MAGIC_LEN;
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5.10.y 6/7] tools/bootconfig: Cleanup bootconfig footer size calculations
2026-09-16 19:07 ` [PATCH 5.10.y 1/7] tools/bootconfig: Simplify expression Sasha Levin
` (3 preceding siblings ...)
2026-09-16 19:07 ` [PATCH 5.10.y 5/7] bootconfig: Replace u16 and u32 with uint16_t and uint32_t Sasha Levin
@ 2026-09-16 19:07 ` Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 7/7] tools/bootconfig: Fix integer overflow and truncation in size checks Sasha Levin
5 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2026-09-16 19:07 UTC (permalink / raw)
To: stable; +Cc: Masami Hiramatsu (Google), Sasha Levin
From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
[ Upstream commit 26dda57695090e05c1a99c3e8f802f862d1ac474 ]
There are many same pattern of 8 + BOOTCONFIG_MAGIC_LEN for calculating
the size of bootconfig footer. Use BOOTCONFIG_FOOTER_SIZE macro to
clean up those magic numbers.
Link: https://lore.kernel.org/all/175211425693.2591046.16029516706923643510.stgit@mhiramat.tok.corp.google.com/
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Stable-dep-of: 462d0b066b61 ("tools/bootconfig: Fix integer overflow and truncation in size checks")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/bootconfig/main.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c
index 358c7007dfe8c..717aa69473a60 100644
--- a/tools/bootconfig/main.c
+++ b/tools/bootconfig/main.c
@@ -162,7 +162,7 @@ static int load_xbc_from_initrd(int fd, char **buf)
if (ret < 0)
return -errno;
- if (stat.st_size < 8 + BOOTCONFIG_MAGIC_LEN)
+ if (stat.st_size < BOOTCONFIG_FOOTER_SIZE)
return 0;
if (lseek(fd, -BOOTCONFIG_MAGIC_LEN, SEEK_END) < 0)
@@ -175,7 +175,7 @@ static int load_xbc_from_initrd(int fd, char **buf)
if (memcmp(magic, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN) != 0)
return 0;
- if (lseek(fd, -(8 + BOOTCONFIG_MAGIC_LEN), SEEK_END) < 0)
+ if (lseek(fd, -BOOTCONFIG_FOOTER_SIZE, SEEK_END) < 0)
return pr_errno("Failed to lseek for size", -errno);
if (read(fd, &size, sizeof(uint32_t)) < 0)
@@ -192,7 +192,7 @@ static int load_xbc_from_initrd(int fd, char **buf)
return -E2BIG;
}
- if (lseek(fd, stat.st_size - (size + 8 + BOOTCONFIG_MAGIC_LEN),
+ if (lseek(fd, stat.st_size - (size + BOOTCONFIG_FOOTER_SIZE),
SEEK_SET) < 0)
return pr_errno("Failed to lseek", -errno);
@@ -323,7 +323,7 @@ static int delete_xbc(const char *path)
ret = fstat(fd, &stat);
if (!ret)
ret = ftruncate(fd, stat.st_size
- - size - 8 - BOOTCONFIG_MAGIC_LEN);
+ - size - BOOTCONFIG_FOOTER_SIZE);
if (ret)
ret = -errno;
} /* Ignore if there is no boot config in initrd */
@@ -353,8 +353,7 @@ static int apply_xbc(const char *path, const char *xbc_path)
csum = xbc_calc_checksum(buf, size);
/* Backup the bootconfig data */
- data = calloc(size + BOOTCONFIG_ALIGN +
- sizeof(uint32_t) + sizeof(uint32_t) + BOOTCONFIG_MAGIC_LEN, 1);
+ data = calloc(size + BOOTCONFIG_ALIGN + BOOTCONFIG_FOOTER_SIZE, 1);
if (!data)
return -ENOMEM;
memcpy(data, buf, size);
@@ -401,7 +400,7 @@ static int apply_xbc(const char *path, const char *xbc_path)
}
/* To align up the total size to BOOTCONFIG_ALIGN, get padding size */
- total_size = stat.st_size + size + sizeof(uint32_t) * 2 + BOOTCONFIG_MAGIC_LEN;
+ total_size = stat.st_size + size + BOOTCONFIG_FOOTER_SIZE;
pad = ((total_size + BOOTCONFIG_ALIGN - 1) & (~BOOTCONFIG_ALIGN_MASK)) - total_size;
size += pad;
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5.10.y 7/7] tools/bootconfig: Fix integer overflow and truncation in size checks
2026-09-16 19:07 ` [PATCH 5.10.y 1/7] tools/bootconfig: Simplify expression Sasha Levin
` (4 preceding siblings ...)
2026-09-16 19:07 ` [PATCH 5.10.y 6/7] tools/bootconfig: Cleanup bootconfig footer size calculations Sasha Levin
@ 2026-09-16 19:07 ` Sasha Levin
5 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2026-09-16 19:07 UTC (permalink / raw)
To: stable; +Cc: Masami Hiramatsu (Google), Sashiko, Sang-Heon Jeon, Sasha Levin
From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
[ Upstream commit 462d0b066b613103f579793031429db2ca23abc0 ]
Sashiko reported that on 32-bit systems, if an attacker crafts size in
the bootconfig footer such that adding BOOTCONFIG_FOOTER_SIZE wraps around
(for instance, if size is 0xFFFFFFFF), the size check in
load_xbc_from_initrd() can be bypassed:
if (stat.st_size < size + BOOTCONFIG_FOOTER_SIZE) {
pr_err("bootconfig size is too big\n");
return -E2BIG;
}
Furthermore, on 64-bit systems with an initrd > 4.29 GB, comparing a
corrupted 32-bit size (e.g. 0xFFFFFFFF) against
stat.st_size - BOOTCONFIG_FOOTER_SIZE can also bypass the check if
size is not bounded. Similarly, load_xbc_file() passes 64-bit stat.st_size
directly into the 32-bit int size parameter of load_xbc_fd(), truncating
large standalone files (>= 2GB).
In both cases, passing 0xFFFFFFFF to load_xbc_fd() truncates to -1,
resulting in malloc(0), an integer overflow in read(), and an
out-of-bounds null-byte write.
Fix this by:
1. Rejecting size > XBC_DATA_MAX or
size > stat.st_size - BOOTCONFIG_FOOTER_SIZE in load_xbc_from_initrd().
2. Rejecting stat.st_size > XBC_DATA_MAX in load_xbc_file() before passing
it to load_xbc_fd().
3. Checking size < 0 || size > XBC_DATA_MAX defensively in load_xbc_fd().
Link: https://lore.kernel.org/all/178905332413.213925.3179977110281463499.stgit@devnote2/
Fixes: 950313ebf79c ("tools: bootconfig: Add bootconfig command")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260909161113.16C691F00A3A@smtp.kernel.org/
Closes: https://lore.kernel.org/all/20260910010137.EE0431F000FF@smtp.kernel.org/
Assisted-by: Antigravity:gemini-3.8-flash
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Sang-Heon Jeon <ekffu200098@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/bootconfig/main.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c
index 717aa69473a60..f35ee15c19167 100644
--- a/tools/bootconfig/main.c
+++ b/tools/bootconfig/main.c
@@ -109,6 +109,9 @@ static int load_xbc_fd(int fd, char **buf, int size)
{
int ret;
+ if (size < 0 || size > XBC_DATA_MAX)
+ return -EINVAL;
+
*buf = malloc(size + 1);
if (!*buf)
return -ENOMEM;
@@ -137,6 +140,13 @@ static int load_xbc_file(const char *path, char **buf)
return ret;
}
+ if (stat.st_size > XBC_DATA_MAX) {
+ pr_err("%s size is too big\n", path);
+ ret = -E2BIG;
+ close(fd);
+ return ret;
+ }
+
ret = load_xbc_fd(fd, buf, stat.st_size);
close(fd);
@@ -187,7 +197,8 @@ static int load_xbc_from_initrd(int fd, char **buf)
csum = le32toh(csum);
/* Wrong size error */
- if (stat.st_size < size + BOOTCONFIG_FOOTER_SIZE) {
+ if (size > XBC_DATA_MAX ||
+ size > stat.st_size - BOOTCONFIG_FOOTER_SIZE) {
pr_err("bootconfig size is too big\n");
return -E2BIG;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-09-16 19:07 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-16 14:16 FAILED: patch "[PATCH] tools/bootconfig: Fix integer overflow and truncation in size" failed to apply to 5.10-stable tree gregkh
2026-09-16 19:07 ` [PATCH 5.10.y 1/7] tools/bootconfig: Simplify expression Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 2/7] bootconfig: Change array value to use child node Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 3/7] bootconfig: Share the checksum function with tools Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 4/7] tools/bootconfig: Print all error message in stderr Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 5/7] bootconfig: Replace u16 and u32 with uint16_t and uint32_t Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 6/7] tools/bootconfig: Cleanup bootconfig footer size calculations Sasha Levin
2026-09-16 19:07 ` [PATCH 5.10.y 7/7] tools/bootconfig: Fix integer overflow and truncation in size checks Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox