linux-doc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
To: "Rob Herring (Arm)" <robh@kernel.org>
Cc: Petr Mladek <pmladek@suse.com>,
	 Steven Rostedt <rostedt@goodmis.org>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	 Sergey Senozhatsky <senozhatsky@chromium.org>,
	 Jonathan Corbet <corbet@lwn.net>,
	 Saravana Kannan <saravanak@google.com>,
	 Andrew Morton <akpm@linux-foundation.org>,
	Zijun Hu <quic_zijuhu@quicinc.com>,
	 linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	 devicetree@vger.kernel.org
Subject: Re: [PATCH] of: Add printf '%pOFm' for generating modalias
Date: Wed, 18 Dec 2024 11:16:52 +0100	[thread overview]
Message-ID: <87wmfxfg8b.fsf@prevas.dk> (raw)
In-Reply-To: <20241217183711.2525863-1-robh@kernel.org> (Rob Herring's message of "Tue, 17 Dec 2024 12:37:09 -0600")

On Tue, Dec 17 2024, "Rob Herring (Arm)" <robh@kernel.org> wrote:

> The callers for of_modalias() generally need the module alias as part of
> some larger string. That results in some error prone manipulation of the
> buffer prepend/append the module alias string. In fact,
> of_device_uevent_modalias() has several issues. First, it's off by one
> too few characters in utilization of the full buffer. Second, the error
> paths leave OF_MODALIAS with a truncated value when in the end nothing
> should be added to the buffer. It is also fragile because it needs
> internal details of struct kobj_uevent_env. add_uevent_var() really
> wants to write the env variable and value in one shot which would need
> either a temporary buffer for value or a format specifier.
>
> Fix these issues by adding a new printf format specifier, "%pOFm". With
> the format specifier in place, simplify all the callers of
> of_modalias(). of_modalias() can also be simplified with vsprintf()
> being the only caller as it avoids the error conditions.
>
> Cc: Zijun Hu <quic_zijuhu@quicinc.com>
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
> ---
>  Documentation/core-api/printk-formats.rst |  1 +
>  drivers/of/device.c                       | 25 ++--------------
>  drivers/of/module.c                       | 35 +++++------------------
>  drivers/of/unittest.c                     |  2 ++
>  include/linux/of.h                        |  8 +++---
>  lib/vsprintf.c                            |  7 +++--
>  6 files changed, 22 insertions(+), 56 deletions(-)

This diffstat lacks a lib/test_printf.c line. Please do add test cases
when extending vsnprintf().

>  
> diff --git a/drivers/of/module.c b/drivers/of/module.c
> index 1e735fc130ad..80879d2abea8 100644
> --- a/drivers/of/module.c
> +++ b/drivers/of/module.c
> @@ -8,21 +8,14 @@
>  #include <linux/slab.h>
>  #include <linux/string.h>
>  
> -ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len)
> +/* Do not use directly, use %pOFm format specifier instead */
> +size_t of_modalias(const struct device_node *np, char *str, size_t len)
>  {
>  	const char *compat;
>  	char *c;
>  	struct property *p;
> -	ssize_t csize;
> -	ssize_t tsize;
> -
> -	/*
> -	 * Prevent a kernel oops in vsnprintf() -- it only allows passing a
> -	 * NULL ptr when the length is also 0. Also filter out the negative
> -	 * lengths...
> -	 */
> -	if ((len > 0 && !str) || len < 0)
> -		return -EINVAL;
> +	size_t csize;
> +	size_t tsize;
>  
>  	/* Name & Type */
>  	/* %p eats all alphanum characters, so %c must be used here */


I took a look at of_modalias() with that change applied. While it does
seem to end up returning the required "total size had the buffer been
big enough", this part

                csize = snprintf(str, len, "C%s", compat);
                tsize += csize;
                if (csize >= len)
                        continue;

seems that it will overwrite/replace a longer compat string with a
shorter, later one, if we happen to be close to the end of the available
space. That's _probably_ not a problem for vsnprintf() itself, or
callers such as kasprintf() that do need the exact size but don't care
about what might have been produced on the first call to determine that
size, but the printf test suite does expect the result of a truncated
vsnprintf() to match the full string up to the truncation point. We can
probably allow certain test cases to opt out of certain sanity checks if
absolutely needed, but perhaps it's simpler to fix of_modalias(). 

Unrelated, I think the space replacement could be simplified to

  if (len > 0)
    strreplace(str, ' ', '_');
  
>  static inline int of_request_module(const struct device_node *np)
> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> index 9d3dac38a3f4..6a4f99b39de0 100644
> --- a/lib/vsprintf.c
> +++ b/lib/vsprintf.c
> @@ -2169,10 +2169,10 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
>  
>  	/* simple case without anything any more format specifiers */
>  	fmt++;
> -	if (fmt[0] == '\0' || strcspn(fmt,"fnpPFcC") > 0)
> +	if (fmt[0] == '\0' || strcspn(fmt,"fnpPFcCm") > 0)
>  		fmt = "f";
>  
> -	for (pass = false; strspn(fmt,"fnpPFcC"); fmt++, pass = true) {
> +	for (pass = false; strspn(fmt,"fnpPFcCm"); fmt++, pass = true) {
>  		int precision;
>  		if (pass) {
>  			if (buf < end)
> @@ -2226,6 +2226,9 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
>  				has_mult = true;
>  			}
>  			break;
> +		case 'm':
> +			buf += of_modalias(dn, buf, end - buf);
> +			break;

This is definitely wrong. I think it's fixable by using

  buf < end ? end - buf : 0

Rasmus

  parent reply	other threads:[~2024-12-18 10:16 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-17 18:37 [PATCH] of: Add printf '%pOFm' for generating modalias Rob Herring (Arm)
2024-12-18  2:21 ` quic_zijuhu
2024-12-18 10:16 ` Rasmus Villemoes [this message]
2024-12-18 15:28   ` Rob Herring
2024-12-18 11:35 ` ssize_t: was: " Petr Mladek
2024-12-18 17:10   ` Rob Herring
2024-12-19 14:44     ` Petr Mladek
2024-12-18 12:27 ` lock in vsprintf(): " Petr Mladek
2024-12-18 14:07   ` John Ogness
2024-12-19 15:05     ` Petr Mladek
2024-12-19 19:11       ` John Ogness
2024-12-20  8:01         ` Petr Mladek
2024-12-30 20:26         ` Rob Herring
2025-01-02 13:06           ` Petr Mladek
2025-01-02 14:02             ` John Ogness
2024-12-18 16:29   ` Rob Herring
2024-12-18 16:31   ` Steven Rostedt
2024-12-23 19:58 ` Andy Shevchenko
2024-12-30 20:52   ` Rob Herring

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87wmfxfg8b.fsf@prevas.dk \
    --to=linux@rasmusvillemoes.dk \
    --cc=akpm@linux-foundation.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=corbet@lwn.net \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pmladek@suse.com \
    --cc=quic_zijuhu@quicinc.com \
    --cc=robh@kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=saravanak@google.com \
    --cc=senozhatsky@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).