diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-23 12:20:54 -1000 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-23 12:20:54 -1000 |
| commit | 90b754d40117b2889bbe847ce7bb4dcf968e7cb8 (patch) | |
| tree | 95c8c91b5a5b33cc7ed7837768fe54dbccd58339 /lib | |
| parent | 3f942403bbad36a120432be69445154891b65398 (diff) | |
| parent | 677f83795fdfc25ddc51b665a9111f5ff199f7ca (diff) | |
| download | linux-90b754d40117b2889bbe847ce7bb4dcf968e7cb8.tar.gz linux-90b754d40117b2889bbe847ce7bb4dcf968e7cb8.zip | |
Merge tag 'bootconfig-v7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
Pull bootconfig updates from Masami Hiramatsu:
"Parser robustness and validation improvements:
- Skip printing early params to cmdline from bootconfig
Suppress early_param keys from /proc/cmdline and warn the user,
since bootconfig does not invoke early_param handlers and silently
ignoring them is misleading
- Reject unexpected data after null character
Detect and reject non-null data following an intermediate null
character in the bootconfig buffer, preventing silently ignored
configuration after an early termination
Code cleanups:
- Merge _xbc_exit() into xbc_exit()
Since memblock_free() now handles late freeing and NULL addresses,
the separate _xbc_exit() helper and its early argument are
unnecessary. Inline it into xbc_exit()
- Remove redundant assignment in xbc_parse_array()
The node->child = 0 assignment after the loop duplicates what
xbc_init_node() already did
- Skip internal tree sanity checks in kernel
Move the node index bounds loop from xbc_verify_tree() into a
userspace-only xbc_sanity_check_tree() to reduce boot-time
overhead, since out-of-bounds indices cannot be produced by
malformed input
- Move BOOTCONFIG_FOOTER_SIZE to include/linux/bootconfig.h
Share the footer size constant between kernel and user-space tools,
replacing the hardcoded (BOOTCONFIG_MAGIC_LEN + 8) expression in
init/main.c
Tooling improvements:
- Remove unused PAGE_SIZE macro from the bootconfig tool
- Consolidate xbc_init() to error message wrapper
Use init_xbc_with_error() for all bootconfig initialization paths
in the tool for simpler and more consistent error handling"
* tag 'bootconfig-v7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
bootconfig: Move BOOTCONFIG_FOOTER_SIZE to include/linux/bootconfig.h
bootconfig: Skip internal tree sanity checks in kernel
tools/bootconfig: Consolidate xbc_init() to error message wrapper
bootconfig: Reject unexpected data after null character
bootconfig: Skip printing early params to cmdline from bootconfig
tools/bootconfig: remove unused PAGE_SIZE macro
bootconfig: remove redundant assignment in xbc_parse_array()
bootconfig: merge _xbc_exit() into xbc_exit()
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/bootconfig.c | 84 |
1 files changed, 53 insertions, 31 deletions
diff --git a/lib/bootconfig.c b/lib/bootconfig.c index 89c88e359179..819685d6c68d 100644 --- a/lib/bootconfig.c +++ b/lib/bootconfig.c @@ -187,12 +187,9 @@ static inline void * __init xbc_alloc_mem(size_t size) return memblock_alloc(size, SMP_CACHE_BYTES); } -static inline void __init xbc_free_mem(void *addr, size_t size, bool early) +static inline void __init xbc_free_mem(void *addr, size_t size) { - if (early) - memblock_free(addr, size); - else if (addr) - memblock_free(addr, size); + memblock_free(addr, size); } #else /* !__KERNEL__ */ @@ -202,7 +199,7 @@ static inline void *xbc_alloc_mem(size_t size) return calloc(1, size); } -static inline void xbc_free_mem(void *addr, size_t size, bool early) +static inline void xbc_free_mem(void *addr, size_t size) { free(addr); } @@ -539,18 +536,21 @@ static char xbc_namebuf[XBC_KEYLEN_MAX] __initdata; #define rest(dst, end) ((end) > (dst) ? (end) - (dst) : 0) /** - * xbc_snprint_cmdline() - Render bootconfig keys under @root as a cmdline string + * xbc_snprint_cmdline_filter() - Render bootconfig keys as cmdline string * @buf: Destination buffer (may be NULL when @size is 0 to query the length) * @size: Size of @buf in bytes * @root: Subtree root whose key=value pairs should be rendered + * @filter: Filter callback (returns true to include, false to skip; may be NULL) + * @data: Private context passed to @filter * * Walk all key/value pairs under @root and emit them as a space-separated * cmdline string into @buf. Values containing whitespace are quoted with - * double quotes. Returns the number of bytes that would be written if @buf - * were large enough (matching snprintf semantics), or a negative errno on - * failure. + * double quotes. Keys for which @filter returns false are omitted. + * Returns the number of bytes that would be written if @buf were large enough + * (matching snprintf semantics), or a negative errno on failure. */ -int __init xbc_snprint_cmdline(char *buf, size_t size, struct xbc_node *root) +int __init xbc_snprint_cmdline_filter(char *buf, size_t size, struct xbc_node *root, + xbc_cmdline_filter_fn filter, void *data) { struct xbc_node *knode, *vnode; const char *val, *q; @@ -582,6 +582,9 @@ int __init xbc_snprint_cmdline(char *buf, size_t size, struct xbc_node *root) if (ret < 0) return ret; + if (filter && !filter(knode, xbc_namebuf, data)) + continue; + vnode = xbc_node_get_child(knode); if (!vnode) { ret = snprintf(buf ? buf + len : NULL, rest(len, size), @@ -836,7 +839,6 @@ static int __init xbc_parse_array(char **__v) return -ENOMEM; *__v = next; } while (c == ','); - node->child = 0; return c; } @@ -1003,9 +1005,30 @@ static int __init xbc_close_brace(char **k, char *n) return __xbc_close_brace(n - 1); } +#ifndef __KERNEL__ +/* Sanity check for regression: node indices must be within bounds */ +static int __init xbc_sanity_check_tree(void) +{ + int i; + + for (i = 0; i < xbc_node_num; i++) { + if (xbc_nodes[i].next >= xbc_node_num) { + return xbc_parse_error("No closing brace", + xbc_node_get_data(xbc_nodes + i)); + } + if (xbc_nodes[i].child >= xbc_node_num) { + return xbc_parse_error("Broken child node", + xbc_node_get_data(xbc_nodes + i)); + } + } + + return 0; +} +#endif + static int __init xbc_verify_tree(void) { - int i, depth; + int depth; size_t len, wlen; struct xbc_node *n, *m; @@ -1022,17 +1045,6 @@ static int __init xbc_verify_tree(void) return -ENOENT; } - for (i = 0; i < xbc_node_num; i++) { - if (xbc_nodes[i].next >= xbc_node_num) { - return xbc_parse_error("No closing brace", - xbc_node_get_data(xbc_nodes + i)); - } - if (xbc_nodes[i].child >= xbc_node_num) { - return xbc_parse_error("Broken child node", - xbc_node_get_data(xbc_nodes + i)); - } - } - /* Key tree limitation check */ n = &xbc_nodes[0]; depth = 1; @@ -1119,24 +1131,30 @@ static int __init xbc_parse_tree(void) } } while (!ret); + if (!ret) { + while (p < xbc_data + xbc_data_size - 1 && *p == '\0') + p++; + if (p < xbc_data + xbc_data_size - 1) + ret = xbc_parse_error("Unexpected data after null character", p); + } + return ret; } /** - * _xbc_exit() - Clean up all parsed bootconfig - * @early: Set true if this is called before budy system is initialized. + * xbc_exit() - Clean up all parsed bootconfig * * This clears all data structures of parsed bootconfig on memory. * If you need to reuse xbc_init() with new boot config, you can * use this. */ -void __init _xbc_exit(bool early) +void __init xbc_exit(void) { - xbc_free_mem(xbc_data, xbc_data_size, early); + xbc_free_mem(xbc_data, xbc_data_size); xbc_data = NULL; xbc_data_size = 0; xbc_node_num = 0; - xbc_free_mem(xbc_nodes, sizeof(struct xbc_node) * XBC_NODE_MAX, early); + xbc_free_mem(xbc_nodes, sizeof(struct xbc_node) * XBC_NODE_MAX); xbc_nodes = NULL; brace_index = 0; } @@ -1189,20 +1207,24 @@ int __init xbc_init(const char *data, size_t size, const char **emsg, int *epos) if (!xbc_nodes) { if (emsg) *emsg = "Failed to allocate bootconfig nodes"; - _xbc_exit(true); + xbc_exit(); return -ENOMEM; } ret = xbc_parse_tree(); if (!ret) ret = xbc_verify_tree(); +#ifndef __KERNEL__ + if (!ret) + ret = xbc_sanity_check_tree(); +#endif if (ret < 0) { if (epos) *epos = xbc_err_pos; if (emsg) *emsg = xbc_err_msg; - _xbc_exit(true); + xbc_exit(); } else { ret = xbc_node_num; } |
