mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Alejandro Colomar <alx@kernel.org>
To: linux-hardening@vger.kernel.org
Cc: Krzysztof Kozlowski <krzk@kernel.org>,
	 "Maciej W. Rozycki" <macro@orcam.me.uk>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	 Alejandro Colomar <alx@kernel.org>,
	Andreas Schwab <schwab@linux-m68k.org>,
	 Andy Shevchenko <andy@kernel.org>,
	Bartosz Golaszewski <brgl@kernel.org>,
	 Daniel Scally <djrscally@gmail.com>,
	Danilo Krummrich <dakr@kernel.org>,
	 Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Hans Verkuil <hverkuil-cisco@xs4all.nl>,
	 Heikki Krogerus <heikki.krogerus@linux.intel.com>,
	Joe Perches <joe@perches.com>, Johan Hovold <johan@kernel.org>,
	 Kees Cook <kees@kernel.org>,
	Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
	 Len Brown <lenb@kernel.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	 Linus Walleij <linusw@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>,
	 "Rafael J. Wysocki" <rafael@kernel.org>,
	Rob Herring <robh@kernel.org>,
	 Sakari Ailus <sakari.ailus@linux.intel.com>,
	Saravana Kannan <saravanak@kernel.org>,
	 Steven Rostedt <rostedt@goodmis.org>,
	Tom Zanussi <zanussi@kernel.org>,
	linux-acpi@vger.kernel.org,  driver-core@lists.linux.dev,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
	 linux-gpio@vger.kernel.org
Subject: [PATCH v3 0/5] Add strprefix() and fix a bug with it
Date: Tue, 10 Nov 2026 16:33:15 +0100	[thread overview]
Message-ID: <cover.1794323750.git.alx@kernel.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 6762 bytes --]

Hi!

str_has_prefix() is based on sizes and lengths, which means it must
overload the valid length 0 to mean not found.  This is a typical
consequence of choosing to design an API around sizes and lengths, and
vanishes when moving to pointer-based similar APIs.

According to its author (Steven R.), str_has_prefix() was never meant to
accept an empty prefix, but that's not documented, and there's no
obvious reason why that would be acceptable for a generic string
function (as opposed to a function very specific to its original use).
Users of strings need a function whose behavior extends naturally to the
empty string, and we can do better, by returning a pointer.  And indeed,
users have ended up using str_has_prefix() with empty prefix, expecting
it to work (as is natural of a generic string API).

This patch set adds strprefix(), deprecates str_has_prefix(), and uses
strprefix() in one place to fix a bug reported by Bartosz.

We can later work on replacing the other uses of str_has_prefix(), which
might hide similar bugs.

This patch set also adds infrastructure to make string functions return
a pointer that is as qualified as the input pointer.

Changes in v2
~~~~~~~~~~~~~

-  Copy the description from str_has_prefix().  [Steve]
-  Add links for the Reported-by tags.
-  Make these APIs const-generic.  [Geert]

I didn't apply some changes requested by reviewers:

-  I didn't remove the deprecation of str_has_prefix(), because I think
   it should not be used in new code.  It remains useful for code that
   is already using it, because rewriting all the surrounding code to
   use pointers instead of offsets might be too risky.  However, for new
   code, strprefix() produces simpler code, and is safer, so I don't see
   why str_has_prefix() would be good in any new code.

-  I didn't rename strprefix() to strsuffix(), because that name would
   be worse (strsuffix() is widely implemented with other semantics, and
   having it different here would lead to confusion and bugs).  Andy
   agreed.

See range-diff below.

Testing
~~~~~~~

I haven't changed the implementation of the function, so haven't re-run
tests.  Since the changes since v2 are only about type safety, with a
new wrapper macro, I have built again with 'allmodconfig', just to make
sure it still compiles.


Have a lovely day!
Alex

v1: <https://lore.kernel.org/linux-hardening/cover.1793876837.git.alx@kernel.org/>
v2: <https://lore.kernel.org/linux-hardening/cover.1793882260.git.alx@kernel.org/>

Alejandro Colomar (5):
  string: Add strprefix(), and deprecate str_has_prefix()
  device property: Fix fwnode_name_eq() for empty node names
  stddef: Add const_cast()
  string: Add [C]QChar_of() and QVoid_of()
  string: Make strprefix() const-qualifier-generic

 drivers/base/property.c  |  5 +---
 include/linux/stddef.h   | 12 ++++++++
 include/linux/string.h   | 63 +++++++++++++++++++++++++++++++++++++---
 lib/tests/string_kunit.c |  9 ++++++
 4 files changed, 81 insertions(+), 8 deletions(-)

Range-diff against v2:
1:  d3b325ecefd1 ! 1:  556766412884 string: Add strprefix(), and deprecate str_has_prefix()
    @@ Commit message
     
         We'll slowly migrate existing code from str_has_prefix() to strprefix().
     
    +    Copy the description from str_has_prefix().
    +
         Reported-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
    +    Link: https://lore.kernel.org/linux-hardening/20261104-fwnode-for-each-prop-v1-1-6e28fe1c72c4@oss.qualcomm.com/
         Cc: Andy Shevchenko <andy@kernel.org>
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
      ## include/linux/string.h ##
     @@ include/linux/string.h: void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
    - 	       sizeof(*(obj)) - offsetof(typeof(*(obj)), member));	\
      })
      
    -+/**
    + /**
    +- * str_has_prefix - Test if a string has a given prefix
    +- * @str: The string to test
    +- * @prefix: The string to see if @str starts with
     + * strprefix - string prefix
     + * @s: The string to be tested
     + * @prefix: The string to see if @s starts with
    -+ *
    -+ * Returns:
    -+ * *  @s+strlen(@prefix) if @s starts with @prefix
    -+ * *  NULL if @s does not start with @prefix
    -+ */
    -+static __always_inline char *strprefix(const char *s, const char *prefix)
    -+{
    -+	size_t len = strlen(prefix);
    -+	return strncmp(s, prefix, len) == 0 ? (char *) s + len : NULL;
    -+}
    -+
    - /**
    -  * str_has_prefix - Test if a string has a given prefix
    -  * @str: The string to test
    -  * @prefix: The string to see if @str starts with
       *
    -+ * DEPRECATED: Use strprefix()
    -+ *
       * A common way to test a prefix of a string is to do:
       *  strncmp(str, prefix, sizeof(prefix) - 1)
       *
       * But this can lead to bugs due to typos, or if prefix is a pointer
     - * and not a constant. Instead use str_has_prefix().
    ++ * and not a constant. Instead use strprefix().
    ++ *
    ++ * Returns:
    ++ * *  @s+strlen(@prefix) if @s starts with @prefix
    ++ * *  NULL if @s does not start with @prefix
    ++ */
    ++static inline char *strprefix(const char *s, const char *prefix)
    ++{
    ++	size_t len = strlen(prefix);
    ++	return strncmp(s, prefix, len) == 0 ? (char *) s + len : NULL;
    ++}
    ++
    ++/**
    ++ * str_has_prefix - Test if a string has a given prefix
    ++ * @str: The string to test
    ++ * @prefix: The string to see if @str starts with
    ++ *
    ++ * DEPRECATED: Use strprefix()
    ++ *
    ++ * A common way to test a prefix of a string is to do:
    ++ *  strncmp(str, prefix, sizeof(prefix) - 1)
    ++ *
    ++ * But this can lead to bugs due to typos, or if prefix is a pointer
     + * and not a constant. Instead use strprefix().
       *
       * Returns:
2:  ac9728afa027 ! 2:  eed085c85f36 device property: Fix fwnode_name_eq() for empty node names
    @@ Commit message
     
         Fixes: a9c8c738066b7 ("device property: Add fwnode_name_eq()")
         Reported-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
    +    Link: https://lore.kernel.org/linux-hardening/20261104-fwnode-for-each-prop-v1-1-6e28fe1c72c4@oss.qualcomm.com/
         Cc: Andy Shevchenko <andy@kernel.org>
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
-:  ------------ > 3:  2bf5cf7baad8 stddef: Add const_cast()
-:  ------------ > 4:  415453a31ebf string: Add [C]QChar_of() and QVoid_of()
-:  ------------ > 5:  35bf6672f84f string: Make strprefix() const-qualifier-generic
-- 
2.55.0


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

             reply	other threads:[~2026-11-10 15:33 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-10 15:33 Alejandro Colomar [this message]
2026-11-10 15:33 ` [PATCH v3 1/5] string: Add strprefix(), and deprecate str_has_prefix() Alejandro Colomar
2026-11-10 15:47   ` Joe Perches
2026-11-10 16:14     ` Alejandro Colomar
2026-11-10 15:33 ` [PATCH v3 2/5] device property: Fix fwnode_name_eq() for empty node names Alejandro Colomar
2026-11-10 15:33 ` [PATCH v3 3/5] stddef: Add const_cast() Alejandro Colomar
2026-11-10 15:33 ` [PATCH v3 4/5] string: Add [C]QChar_of() and QVoid_of() Alejandro Colomar
2026-11-10 15:33 ` [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic Alejandro Colomar
2026-11-10 16:32   ` Joe Perches

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=cover.1794323750.git.alx@kernel.org \
    --to=alx@kernel.org \
    --cc=andy@kernel.org \
    --cc=brgl@kernel.org \
    --cc=dakr@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=djrscally@gmail.com \
    --cc=driver-core@lists.linux.dev \
    --cc=geert@linux-m68k.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=hverkuil-cisco@xs4all.nl \
    --cc=joe@perches.com \
    --cc=johan@kernel.org \
    --cc=kees@kernel.org \
    --cc=krzk@kernel.org \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=lenb@kernel.org \
    --cc=linusw@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=macro@orcam.me.uk \
    --cc=namhyung@kernel.org \
    --cc=rafael@kernel.org \
    --cc=robh@kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=sakari.ailus@linux.intel.com \
    --cc=saravanak@kernel.org \
    --cc=schwab@linux-m68k.org \
    --cc=torvalds@linux-foundation.org \
    --cc=zanussi@kernel.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

all inboxes | Powered by JetHome®