bootconfig: render descendant keys when xbc_snprint_cmdline() root has a value

xbc_node_for_each_key_value() walks to the first leaf under @root, and
when @root is itself a leaf it yields @root. That happens not only for
an empty "kernel {}" subtree, but also when @root carries both a value
and subkeys, e.g.

	kernel = x
	kernel.foo = bar

Here @root ("kernel") is a leaf because its first child is the value
node "x", so the iterator returns @root first. Feeding @root back into
xbc_node_compose_key_after(root, root) returns -EINVAL, which the only
in-kernel caller papers over with a "len <= 0" check -- but the
follow-up tools/bootconfig -C user propagates the error and turns such
a bootconfig into a build failure. Worse, short-circuiting the whole
call on a leaf @root would silently drop the valid "kernel.foo = bar"
descendant that this patch should render.

Skip @root inside the loop instead of bailing out: the value-only entry
is dropped (it is rendered through the "kernel" cmdline path, not here),
while real descendant keys are still emitted. An entirely empty subtree
now renders nothing and returns 0 rather than -EINVAL, matching the
"nothing to render is not an error" semantics expected by the new
build-time caller.

Link: https://lore.kernel.org/all/20260626-bootconfig_using_tools-v7-2-24ab72139c29@debian.org/

Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
This commit is contained in:
Breno Leitao
2026-07-02 21:15:44 +09:00
committed by Masami Hiramatsu (Google)
parent 4a50a141f0
commit 7afe198fc1
+11
View File
@@ -440,6 +440,17 @@ int __init xbc_snprint_cmdline(char *buf, size_t size, struct xbc_node *root)
* itself is well defined and returns the would-be length.
*/
xbc_node_for_each_key_value(root, knode, val) {
/*
* An empty or value-only @root (e.g. "kernel {}" or
* "kernel = x", possibly alongside "kernel.foo = bar")
* yields @root itself here. Skip it: composing a key for it
* would fail with -EINVAL, yet any real descendant keys must
* still be rendered. An entirely empty subtree then renders
* nothing and returns 0 rather than an error.
*/
if (knode == root)
continue;
ret = xbc_node_compose_key_after(root, knode,
xbc_namebuf, XBC_KEYLEN_MAX);
if (ret < 0)