From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A33DD39CCF9 for ; Tue, 28 Jul 2026 17:07:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785258431; cv=none; b=FSrmMJRAorxXXwdUf4PeXbQn/BmpJdoxPZqH7VmBYx+QIOZGnpPdupPEkDneAs0oIbhKw1CZ3CjQJX3nkbKATxxU4LMwhsMbZ04pDX811i/A6auqibxDSAMzjOAlG6ow5o1TKeAFysBDVOEvjgIiFZp0IZ5SQ6Je4j4bXInxyU0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785258431; c=relaxed/simple; bh=iLRTRfwhmUa45820fTis07Qp8Ro7YFEbt/HR84uk+cY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=G4iXQcJT2u/3BhpYz4Pg9mAjCNa8PdTt58LOxYEL9L6xl0OrHg2nGk7EI0MxO58QDodbPhRUtisyOST2ZDJbZ4QVthsS/ihVSvsmDNkJSIlwlNRbeggSXGnMNFLqtaP/sP84BKO++6S9woEm9osX64IoJgkuqNbenh80jggF8ds= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=i7i/gizN; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="i7i/gizN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 040921F00A3A; Tue, 28 Jul 2026 17:07:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1785258430; bh=oeEvQXhL58OBLrBWbI8Uh5YSc7jd5V/5jht240nD/74=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=i7i/gizNOZyhJMRu35W+u4E71vBTLdHfe/UeA7f58t57O762A3H96PYGa1UuBryBM 7qLIciNkqPBqnLjcudAVxhRdSS6hOARVJ8n8guhr+36niiijulb/Na5vfwacC7wLQw 9MO1nMiKcmUcaHSR3xWmWmy9oxrH7TVbcf0ItXhckaJQJ2K7RzWvbHhylxTwGx+vkw Bi0YDmi9HJjui91bGojDNvenhMeSmDss9dhV/vVIhGu0r0lbXE7i73yIQihe66SQJU nCKpoLCoxPz26PnKlMD2Fp7ALncNDklwWMtydK088Ns19nsf+R764MclayQ/yu1GNt +2AnC6vI9/e6w== From: Sasha Levin To: stable@vger.kernel.org Cc: Breno Leitao , "Masami Hiramatsu (Google)" , Sasha Levin Subject: [PATCH 6.12.y 1/2] bootconfig: move xbc_snprint_cmdline() to lib/bootconfig.c Date: Tue, 28 Jul 2026 13:07:07 -0400 Message-ID: <20260728170708.183603-1-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <2026072112-player-datebook-ddb8@gregkh> References: <2026072112-player-datebook-ddb8@gregkh> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Breno Leitao [ Upstream commit 5a643e4623238e14b03d75ca0d4eda0645720cee ] Move xbc_snprint_cmdline() from init/main.c to lib/bootconfig.c so the function (and its xbc_namebuf scratch buffer) becomes part of the shared parser library. tools/bootconfig already compiles lib/bootconfig.c directly, which lets a follow-up patch reuse the same renderer in the userspace tool to convert a bootconfig file into a flat cmdline string at build time. No functional change. Link: https://lore.kernel.org/all/20260508-bootconfig_using_tools-v1-1-1132219aa773@debian.org/ Signed-off-by: Breno Leitao Signed-off-by: Masami Hiramatsu (Google) Stable-dep-of: dec4d8118c17 ("bootconfig: fix NULL-pointer arithmetic in xbc_snprint_cmdline()") Signed-off-by: Sasha Levin --- include/linux/bootconfig.h | 3 ++ init/main.c | 45 ------------------------------ lib/bootconfig.c | 56 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 45 deletions(-) diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h index 3f4b4ac527ca28..ade862f8130742 100644 --- a/include/linux/bootconfig.h +++ b/include/linux/bootconfig.h @@ -265,6 +265,9 @@ static inline struct xbc_node * __init xbc_node_get_subkey(struct xbc_node *node int __init xbc_node_compose_key_after(struct xbc_node *root, struct xbc_node *node, char *buf, size_t size); +/* Render key/value pairs under @root as a flat cmdline string */ +int __init xbc_snprint_cmdline(char *buf, size_t size, struct xbc_node *root); + /** * xbc_node_compose_key() - Compose full key string of the XBC node * @node: An XBC node. diff --git a/init/main.c b/init/main.c index dca88ac54c4357..df9db4d47868a3 100644 --- a/init/main.c +++ b/init/main.c @@ -318,51 +318,6 @@ static void * __init get_boot_config_from_initrd(size_t *_size) #ifdef CONFIG_BOOT_CONFIG -static char xbc_namebuf[XBC_KEYLEN_MAX] __initdata; - -#define rest(dst, end) ((end) > (dst) ? (end) - (dst) : 0) - -static int __init xbc_snprint_cmdline(char *buf, size_t size, - struct xbc_node *root) -{ - struct xbc_node *knode, *vnode; - char *end = buf + size; - const char *val, *q; - int ret; - - xbc_node_for_each_key_value(root, knode, val) { - ret = xbc_node_compose_key_after(root, knode, - xbc_namebuf, XBC_KEYLEN_MAX); - if (ret < 0) - return ret; - - vnode = xbc_node_get_child(knode); - if (!vnode) { - ret = snprintf(buf, rest(buf, end), "%s ", xbc_namebuf); - if (ret < 0) - return ret; - buf += ret; - continue; - } - xbc_array_for_each_value(vnode, val) { - /* - * For prettier and more readable /proc/cmdline, only - * quote the value when necessary, i.e. when it contains - * whitespace. - */ - q = strpbrk(val, " \t\r\n") ? "\"" : ""; - ret = snprintf(buf, rest(buf, end), "%s=%s%s%s ", - xbc_namebuf, q, val, q); - if (ret < 0) - return ret; - buf += ret; - } - } - - return buf - (end - size); -} -#undef rest - /* Make an extra command line under given key word */ static char * __init xbc_make_cmdline(const char *key) { diff --git a/lib/bootconfig.c b/lib/bootconfig.c index 5d3802eba52a3b..c149ee8eb55dfc 100644 --- a/lib/bootconfig.c +++ b/lib/bootconfig.c @@ -405,6 +405,62 @@ const char * __init xbc_node_find_next_key_value(struct xbc_node *root, return ""; /* No value key */ } +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 + * @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 + * + * 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. + */ +int __init xbc_snprint_cmdline(char *buf, size_t size, struct xbc_node *root) +{ + struct xbc_node *knode, *vnode; + char *end = buf + size; + const char *val, *q; + int ret; + + xbc_node_for_each_key_value(root, knode, val) { + ret = xbc_node_compose_key_after(root, knode, + xbc_namebuf, XBC_KEYLEN_MAX); + if (ret < 0) + return ret; + + vnode = xbc_node_get_child(knode); + if (!vnode) { + ret = snprintf(buf, rest(buf, end), "%s ", xbc_namebuf); + if (ret < 0) + return ret; + buf += ret; + continue; + } + xbc_array_for_each_value(vnode, val) { + /* + * For prettier and more readable /proc/cmdline, only + * quote the value when necessary, i.e. when it contains + * whitespace. + */ + q = strpbrk(val, " \t\r\n") ? "\"" : ""; + ret = snprintf(buf, rest(buf, end), "%s=%s%s%s ", + xbc_namebuf, q, val, q); + if (ret < 0) + return ret; + buf += ret; + } + } + + return buf - (end - size); +} +#undef rest + /* XBC parse and tree build */ static int __init xbc_init_node(struct xbc_node *node, char *data, uint32_t flag) -- 2.53.0