* [PATCH v6 01/19] string: Add streq()
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
@ 2026-11-14 15:21 ` Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 02/19] string: Add strprefix() Alejandro Colomar
` (17 subsequent siblings)
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:21 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio
[-- Attachment #1: Type: text/plain, Size: 2025 bytes --]
The return value of strcmp(3) being reversed makes it prone to mistakes.
Since most of the time we're only interested in simple equality, add
this API for those cases.
This removes some driver-specific definitions of streq(3).
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
drivers/clk/socfpga/clk-gate-a10.c | 2 --
drivers/clk/socfpga/clk.h | 1 -
include/linux/string.h | 12 ++++++++++++
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c
index ba12179061b3..df9f660db8a0 100644
--- a/drivers/clk/socfpga/clk-gate-a10.c
+++ b/drivers/clk/socfpga/clk-gate-a10.c
@@ -11,8 +11,6 @@
#include "clk.h"
-#define streq(a, b) (strcmp((a), (b)) == 0)
-
#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw)
/* SDMMC Group for System Manager defines */
diff --git a/drivers/clk/socfpga/clk.h b/drivers/clk/socfpga/clk.h
index 9a2fb2dde5b8..2008e6f34a5d 100644
--- a/drivers/clk/socfpga/clk.h
+++ b/drivers/clk/socfpga/clk.h
@@ -19,7 +19,6 @@
#define SOCFPGA_MAX_PARENTS 5
-#define streq(a, b) (strcmp((a), (b)) == 0)
#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \
((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0))
diff --git a/include/linux/string.h b/include/linux/string.h
index 6cb5cdd01158..9b3e578d9aca 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -14,6 +14,18 @@
#include <linux/stdarg.h>
#include <uapi/linux/string.h>
+/**
+ * streq - strings equal
+ *
+ * @s1: string to compare
+ * @s2: string to compare
+ *
+ * Compare two strings for equality.
+ *
+ * Return: true iff the strings are equal
+ */
+#define streq(s1, s2) (strcmp(s1, s2) == 0)
+
extern char *strndup_user(const char __user *, long);
extern void *memdup_user(const void __user *, size_t) __realloc_size(2);
extern void *vmemdup_user(const void __user *, size_t) __realloc_size(2);
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v6 02/19] string: Add strprefix()
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
2026-11-14 15:21 ` [PATCH v6 01/19] string: Add streq() Alejandro Colomar
@ 2026-11-14 15:22 ` Alejandro Colomar
2026-11-14 15:28 ` Joe Perches
2026-11-14 15:22 ` [PATCH v6 03/19] string: Document corner-case misbehavior in str_has_prefix() for empty prefix Alejandro Colomar
` (16 subsequent siblings)
18 siblings, 1 reply; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:22 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio, Bartosz Golaszewski
[-- Attachment #1: Type: text/plain, Size: 3851 bytes --]
As Bartosz reported, str_has_prefix() has a bug: it can't differentiate
between an empty prefix matching an empty string from a non-matching
prefix. This is a fundamental design flaw in this API, and not
something that can be fixed.
As always, this is a consequence of choosing sizes instead of pointers.
Sizes are often the wrong choice. In this specific case, pointers are
more capable of differentiating these cases, as NULL is a special
sentinel value that doesn't need to overload a valid value.
Let's implement strprefix(), a function that returns a pointer
right after the prefix if found, and a null pointer if not found.
We'll slowly migrate existing code from str_has_prefix() to strprefix().
Move the description from str_has_prefix(), and describe
str_has_prefix() by comparing it to strprefix().
Closes: https://lore.kernel.org/linux-hardening/20261104-fwnode-for-each-prop-v1-1-6e28fe1c72c4@oss.qualcomm.com/
Reported-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
include/linux/string.h | 29 ++++++++++++++++++++++++-----
lib/tests/string_kunit.c | 9 +++++++++
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/include/linux/string.h b/include/linux/string.h
index 9b3e578d9aca..14e825e902eb 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -557,16 +557,35 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
sizeof(*(obj)) - offsetof(typeof(*(obj)), member)); \
})
+/**
+ * strprefix - string prefix
+ * @s: The string to be tested
+ * @prefix: The string to see if @s starts with
+ *
+ * A common way to test a prefix of a string is to do:
+ * strncmp(s, 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:
+ * * @s + strlen(@prefix) if @s starts with @prefix
+ * * NULL if @s does not start with @prefix
+ */
+__attribute__((nonnull(1, 2)))
+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
*
- * 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().
+ * This is similar to strprefix(), but returns an offset instead of
+ * a pointer.
*
* Returns:
* * strlen(@prefix) if @str starts with @prefix
diff --git a/lib/tests/string_kunit.c b/lib/tests/string_kunit.c
index 0819ace5b027..f603e89866d1 100644
--- a/lib/tests/string_kunit.c
+++ b/lib/tests/string_kunit.c
@@ -287,6 +287,14 @@ static void string_test_strspn(struct kunit *test)
}
}
+static void string_test_strprefix(struct kunit *test)
+{
+ KUNIT_ASSERT_TRUE(test, streq(strprefix("foobar", "foo"), "bar"));
+ KUNIT_ASSERT_TRUE(test, streq(strprefix("foobar", ""), "foobar"));
+ KUNIT_ASSERT_TRUE(test, streq(strprefix("foobar", "foobar"), ""));
+ KUNIT_ASSERT_NULL(test, strprefix("foobar", "bar"));
+}
+
static char strcmp_buffer1[STRCMP_LARGE_BUF_LEN];
static char strcmp_buffer2[STRCMP_LARGE_BUF_LEN];
@@ -891,6 +899,7 @@ static struct kunit_case string_test_cases[] = {
KUNIT_CASE(string_test_strnchr),
KUNIT_CASE(string_test_strrchr),
KUNIT_CASE(string_test_strspn),
+ KUNIT_CASE(string_test_strprefix),
KUNIT_CASE(string_test_strcmp),
KUNIT_CASE(string_test_strcmp_long_strings),
KUNIT_CASE(string_test_strncmp),
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v6 02/19] string: Add strprefix()
2026-11-14 15:22 ` [PATCH v6 02/19] string: Add strprefix() Alejandro Colomar
@ 2026-11-14 15:28 ` Joe Perches
0 siblings, 0 replies; 24+ messages in thread
From: Joe Perches @ 2026-11-14 15:28 UTC (permalink / raw)
To: Alejandro Colomar, linux-hardening
Cc: Krzysztof Kozlowski, Maciej W. Rozycki, Geert Uytterhoeven,
Andreas Schwab, Andy Shevchenko, Bartosz Golaszewski,
Daniel Scally, Danilo Krummrich, Greg Kroah-Hartman, Hans Verkuil,
Heikki Krogerus, Johan Hovold, Kees Cook, Laurent Pinchart,
Len Brown, Linus Torvalds, Linus Walleij, Namhyung Kim,
Rafael J. Wysocki, Rob Herring, Sakari Ailus, Saravana Kannan,
Steven Rostedt, Tom Zanussi, linux-acpi, driver-core,
linux-kernel, devicetree, linux-gpio, Bartosz Golaszewski
On Sat, 2026-11-14 at 16:22 +0100, Alejandro Colomar wrote:
> As Bartosz reported, str_has_prefix() has a bug: it can't differentiate
> between an empty prefix matching an empty string from a non-matching
> prefix. This is a fundamental design flaw in this API, and not
> something that can be fixed.
I still think this description is poor.
It's neither a bug nor a flaw.
It's a design choice.
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v6 03/19] string: Document corner-case misbehavior in str_has_prefix() for empty prefix
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
2026-11-14 15:21 ` [PATCH v6 01/19] string: Add streq() Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 02/19] string: Add strprefix() Alejandro Colomar
@ 2026-11-14 15:22 ` Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 04/19] device property: Fix fwnode_name_eq() for empty node names Alejandro Colomar
` (15 subsequent siblings)
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:22 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio, Bartosz Golaszewski
[-- Attachment #1: Type: text/plain, Size: 1284 bytes --]
For an empty prefix, this function returns a value that can't be
distinguished from a non-matching prefix. This is wrong, since an empty
prefix is present in every string, and has resulted in bugs in code that
called this function without knowing this issue. Let's document it.
Closes: https://lore.kernel.org/linux-hardening/20261104-fwnode-for-each-prop-v1-1-6e28fe1c72c4@oss.qualcomm.com/
Reported-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Suggested-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
include/linux/string.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/linux/string.h b/include/linux/string.h
index 14e825e902eb..58b8b7c02b8d 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -587,6 +587,10 @@ static inline char *strprefix(const char *s, const char *prefix)
* This is similar to strprefix(), but returns an offset instead of
* a pointer.
*
+ * Unlike for strprefix(), if the prefix is an empty string, the
+ * behavior is undefined. If you need to support arbitrary prefixes,
+ * use strprefix().
+ *
* Returns:
* * strlen(@prefix) if @str starts with @prefix
* * 0 if @str does not start with @prefix
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v6 04/19] device property: Fix fwnode_name_eq() for empty node names
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (2 preceding siblings ...)
2026-11-14 15:22 ` [PATCH v6 03/19] string: Document corner-case misbehavior in str_has_prefix() for empty prefix Alejandro Colomar
@ 2026-11-14 15:22 ` Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 05/19] stddef: Add const_cast() Alejandro Colomar
` (14 subsequent siblings)
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:22 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio, Bartosz Golaszewski
[-- Attachment #1: Type: text/plain, Size: 1512 bytes --]
str_has_prefix() returns the prefix length on match and 0 on mismatch,
so the mistmatch case can't be told from "empty prefix matched an empty
string".
For instance: the OF root node's name as returned by
fwnode_get_name() is "" and will return 0 for any name matched against
it and since len is 0 too, fwnode_name_eq() will return true.
Let's use strprefix() instead, which also makes this function simpler.
Fixes: a9c8c738066b7 ("device property: Add fwnode_name_eq()")
Closes: https://lore.kernel.org/linux-hardening/20261104-fwnode-for-each-prop-v1-1-6e28fe1c72c4@oss.qualcomm.com/
Reported-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
drivers/base/property.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 51109794d727..7728116e2968 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -692,15 +692,12 @@ const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode)
bool fwnode_name_eq(const struct fwnode_handle *fwnode, const char *name)
{
const char *node_name;
- ptrdiff_t len;
node_name = fwnode_get_name(fwnode);
if (!node_name)
return false;
- len = strchrnul(node_name, '@') - node_name;
-
- return str_has_prefix(node_name, name) == len;
+ return strprefix(node_name, name) == strchrnul(node_name, '@');
}
EXPORT_SYMBOL_GPL(fwnode_name_eq);
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v6 05/19] stddef: Add const_cast()
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (3 preceding siblings ...)
2026-11-14 15:22 ` [PATCH v6 04/19] device property: Fix fwnode_name_eq() for empty node names Alejandro Colomar
@ 2026-11-14 15:22 ` Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 06/19] string: Add [C]QChar_of() and QVoid_of() Alejandro Colomar
` (13 subsequent siblings)
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:22 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio, David Laight
[-- Attachment #1: Type: text/plain, Size: 1135 bytes --]
This macro serves to cast const away without risking unwanted
conversions due to mistakes in the cast.
It's similar to C++'s const_cast(), but it is more restrictive: it can
only cast away 'const', and not arbitrary qualifiers.
Cc: David Laight <david.laight.linux@gmail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
include/linux/stddef.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/include/linux/stddef.h b/include/linux/stddef.h
index e1851c50c89b..26c657465e60 100644
--- a/include/linux/stddef.h
+++ b/include/linux/stddef.h
@@ -194,4 +194,15 @@ enum {
#define TRAILING_OVERLAP(TYPE, NAME, FAM, MEMBERS) \
__TRAILING_OVERLAP(TYPE, NAME, FAM, /* no attrs */, MEMBERS)
+/**
+ * const_cast() - At most, drop const in the left-most derivation of a pointer
+ *
+ * @T: Type for the cast.
+ * @p: Pointer to be casted.
+ *
+ * Cast @p to type @T. The macro verifies that @p is of type const @T.
+ * This avoids mistakes that change anything other than 'const' in a cast.
+ */
+#define const_cast(T, p) _Generic(p, const T: (T) (p))
+
#endif
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v6 06/19] string: Add [C]QChar_of() and QVoid_of()
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (4 preceding siblings ...)
2026-11-14 15:22 ` [PATCH v6 05/19] stddef: Add const_cast() Alejandro Colomar
@ 2026-11-14 15:22 ` Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 07/19] string: Make strprefix() const-qualifier-generic Alejandro Colomar
` (12 subsequent siblings)
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:22 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio
[-- Attachment #1: Type: text/plain, Size: 1613 bytes --]
These macros serve to implement qualifier-generic macros as those
specified in ISO C23.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
include/linux/string.h | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/include/linux/string.h b/include/linux/string.h
index 58b8b7c02b8d..ede8883c99a1 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -14,6 +14,36 @@
#include <linux/stdarg.h>
#include <uapi/linux/string.h>
+/**
+ * QVoid_of - qualified void of
+ *
+ * @p: Pointer to test for qualifiers
+ *
+ * This macro produces the type name 'void',
+ * qualified with any qualifiers present in the element of @p.
+ */
+#define QVoid_of(p) typeof(*(__QVoidptr_of(p)){0})
+#define __QVoidptr_of(p) typeof(1?(p):(void*){0})
+
+/**
+ * QChar_of - qualified char of
+ *
+ * @Q: Qualifier to test.
+ * @p: Pointer to test for the @Q qualifier
+ *
+ * This macro produces the type name 'char',
+ * @Q-qualified iff the input pointer points to a @Q-qualified element.
+ */
+#define QChar_of(Q, p) typeof \
+( \
+ _Generic((QVoid_of(p) *){0}, \
+ Q void *: (Q char){0}, \
+ void *: ( char){0} \
+ ) \
+)
+// CQChar_of - const qualified char of
+#define CQChar_of(p) QChar_of(const, p)
+
/**
* streq - strings equal
*
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v6 07/19] string: Make strprefix() const-qualifier-generic
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (5 preceding siblings ...)
2026-11-14 15:22 ` [PATCH v6 06/19] string: Add [C]QChar_of() and QVoid_of() Alejandro Colomar
@ 2026-11-14 15:22 ` Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 08/19] perf map: Use bool for return type instead of int Alejandro Colomar
` (11 subsequent siblings)
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:22 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio, David Laight
[-- Attachment #1: Type: text/plain, Size: 1511 bytes --]
Add a macro of the same name, which returns a pointer that is
const-qualified iff the input string is const-qualified. The return
type is a possibly-const-qualified pointer to char, even if the input
is a possibly-const-qualified pointer to void, which is why we require
the CQChar_of() macro.
The function now needs to return 'const char *', because const_cast()
can only drop const, but never add it.
Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Joe Perches <joe@perches.com>
Cc: David Laight <david.laight.linux@gmail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
include/linux/string.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/linux/string.h b/include/linux/string.h
index ede8883c99a1..013c6169def0 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -603,11 +603,12 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
* * NULL if @s does not start with @prefix
*/
__attribute__((nonnull(1, 2)))
-static inline char *strprefix(const char *s, const char *prefix)
+static inline const char *strprefix(const char *s, const char *prefix)
{
size_t len = strlen(prefix);
- return strncmp(s, prefix, len) == 0 ? (char *) s + len : NULL;
+ return strncmp(s, prefix, len) == 0 ? s + len : NULL;
}
+#define strprefix(s, pfx) const_cast(CQChar_of(s) *, strprefix(s, pfx))
/**
* str_has_prefix - Test if a string has a given prefix
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v6 08/19] perf map: Use bool for return type instead of int
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (6 preceding siblings ...)
2026-11-14 15:22 ` [PATCH v6 07/19] string: Make strprefix() const-qualifier-generic Alejandro Colomar
@ 2026-11-14 15:22 ` Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 09/19] string: Make strstarts() a legacy alias for strprefix() Alejandro Colomar
` (10 subsequent siblings)
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:22 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio
[-- Attachment #1: Type: text/plain, Size: 729 bytes --]
This is not strictly necessary, but is more robust and readable.
We already use bool in that file, so this improves consistency too.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
tools/perf/util/map.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 41cdddc987ee..944f10d32796 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -16,7 +16,7 @@
#include "thread.h"
#include "vdso.h"
-static inline int is_android_lib(const char *filename)
+static inline bool is_android_lib(const char *filename)
{
return strstarts(filename, "/data/app-lib/") ||
strstarts(filename, "/system/lib/");
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v6 09/19] string: Make strstarts() a legacy alias for strprefix()
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (7 preceding siblings ...)
2026-11-14 15:22 ` [PATCH v6 08/19] perf map: Use bool for return type instead of int Alejandro Colomar
@ 2026-11-14 15:22 ` Alejandro Colomar
2026-11-14 15:33 ` sashiko-bot
2026-11-14 15:23 ` [PATCH v6 10/19] platform/x86: hp-bioscfg: Rename local variable Alejandro Colomar
` (9 subsequent siblings)
18 siblings, 1 reply; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:22 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio
[-- Attachment #1: Type: text/plain, Size: 1878 bytes --]
strprefix() is drop-in compatible with strstarts() --but see caveats
below--, and provides more functionality for cases where we're
interested in the position where the prefix ends in the string.
strprefix() returns a pointer that can be converted to bool. This is
converted implicitly in most places, but if the target type is not bool,
then it might be problematic and require an explicit conversion with !!.
I checked that we don't need this anywhere, and also, I expect the
compiler would likely diagnose in such a case, so this should be safe.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
include/linux/string.h | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/include/linux/string.h b/include/linux/string.h
index 013c6169def0..0a466360dbb3 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -609,6 +609,7 @@ static inline const char *strprefix(const char *s, const char *prefix)
return strncmp(s, prefix, len) == 0 ? s + len : NULL;
}
#define strprefix(s, pfx) const_cast(CQChar_of(s) *, strprefix(s, pfx))
+#define strstarts(s, pfx) strprefix(s, pfx) // legacy alias
/**
* str_has_prefix - Test if a string has a given prefix
@@ -632,19 +633,6 @@ static __always_inline size_t str_has_prefix(const char *str, const char *prefix
return strncmp(str, prefix, len) == 0 ? len : 0;
}
-/**
- * strstarts - does @str start with @prefix?
- * @str: string to examine
- * @prefix: prefix to look for.
- *
- * Returns:
- * True if @str begins with @prefix. False in all other cases.
- */
-static inline bool strstarts(const char *str, const char *prefix)
-{
- return strncmp(str, prefix, strlen(prefix)) == 0;
-}
-
/**
* strends - Check if a string ends with another string.
* @str: NULL-terminated string to check against @suffix
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v6 09/19] string: Make strstarts() a legacy alias for strprefix()
2026-11-14 15:22 ` [PATCH v6 09/19] string: Make strstarts() a legacy alias for strprefix() Alejandro Colomar
@ 2026-11-14 15:33 ` sashiko-bot
0 siblings, 0 replies; 24+ messages in thread
From: sashiko-bot @ 2026-11-14 15:33 UTC (permalink / raw)
To: Alejandro Colomar; +Cc: devicetree, linux-gpio, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [High] string: strstarts() macro expansion shadowed by local strprefix
variable
--
commit e4b277f22320c7ff4dbc9e8cc88221ad43eb8ba6
Author: Alejandro Colomar <alx@kernel.org>
string: Make strstarts() a legacy alias for strprefix()
This commit replaces the inline strstarts() function with a macro alias for
strprefix().
> diff --git a/include/linux/string.h b/include/linux/string.h
> index 013c6169def05..0a466360dbb39 100644
> --- a/include/linux/string.h
> +++ b/include/linux/string.h
> @@ -609,6 +609,7 @@ static inline const char *strprefix(const char *s, const char *prefix)
> return strncmp(s, prefix, len) == 0 ? s + len : NULL;
> }
> #define strprefix(s, pfx) const_cast(CQChar_of(s) *, strprefix(s, pfx))
> +#define strstarts(s, pfx) strprefix(s, pfx) // legacy alias
[Severity: High]
Does expanding strstarts() to strprefix() break the build when a caller has
a local variable named strprefix?
drivers/platform/x86/hp/hp-bioscfg/spmobj-attributes.c:hp_populate_security_buffer() {
u16 *auth = authbuf;
char *strprefix = NULL;
int ret = 0;
if (strstarts(authentication, BEAM_PREFIX)) {
...
}
Because the strprefix() macro expands to a call to the inline function
strprefix() in the caller's scope, the local pointer variable strprefix
shadows the function identifier and breaks compilation when
CONFIG_HP_BIOSCFG is enabled. A later patch in this series, commit
"platform/x86: hp-bioscfg: Rename local variable", renames that variable to
prefix and should be ordered before this commit to keep the series
bisectable.
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1794667407.git.alx@kernel.org?part=9
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v6 10/19] platform/x86: hp-bioscfg: Rename local variable
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (8 preceding siblings ...)
2026-11-14 15:22 ` [PATCH v6 09/19] string: Make strstarts() a legacy alias for strprefix() Alejandro Colomar
@ 2026-11-14 15:23 ` Alejandro Colomar
2026-11-14 15:23 ` [PATCH v6 11/19] treewide: s/strstarts/strprefix/g Alejandro Colomar
` (8 subsequent siblings)
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:23 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio
[-- Attachment #1: Type: text/plain, Size: 1425 bytes --]
strprefix shadows a function of the same name. Let's rename it.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
drivers/platform/x86/hp/hp-bioscfg/spmobj-attributes.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/platform/x86/hp/hp-bioscfg/spmobj-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/spmobj-attributes.c
index 343b2356943e..a38d200bd0d9 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/spmobj-attributes.c
+++ b/drivers/platform/x86/hp/hp-bioscfg/spmobj-attributes.c
@@ -67,7 +67,7 @@ size_t hp_calculate_security_buffer(const char *authentication)
int hp_populate_security_buffer(u16 *authbuf, const char *authentication)
{
u16 *auth = authbuf;
- char *strprefix = NULL;
+ char *prefix = NULL;
int ret = 0;
if (strstarts(authentication, BEAM_PREFIX)) {
@@ -87,13 +87,13 @@ int hp_populate_security_buffer(u16 *authbuf, const char *authentication)
*/
/* append UTF_PREFIX to part and then convert it to unicode */
- strprefix = kasprintf(GFP_KERNEL, "%s%s", UTF_PREFIX,
+ prefix = kasprintf(GFP_KERNEL, "%s%s", UTF_PREFIX,
authentication);
- if (!strprefix)
+ if (!prefix)
return -ENOMEM;
- auth = hp_ascii_to_utf16_unicode(auth, strprefix);
- kfree(strprefix);
+ auth = hp_ascii_to_utf16_unicode(auth, prefix);
+ kfree(prefix);
if (!auth) {
ret = -EINVAL;
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v6 11/19] treewide: s/strstarts/strprefix/g
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (9 preceding siblings ...)
2026-11-14 15:23 ` [PATCH v6 10/19] platform/x86: hp-bioscfg: Rename local variable Alejandro Colomar
@ 2026-11-14 15:23 ` Alejandro Colomar
2026-11-14 15:23 ` [PATCH v6 12/19] string: Remove strstarts() Alejandro Colomar
` (7 subsequent siblings)
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:23 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio
[-- Attachment #1: Type: text/plain, Size: 35322 bytes --]
This was a scripted change:
$ git ls-files \
| grep '\.[ch]$' \
| grep -v -e ^tools/ -e ^scripts/ -e ^include/ \
| xargs grep -l strstarts \
| xargs sed -i 's/strstarts/strprefix/g';
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
arch/arm/kernel/module.c | 12 ++---
arch/mips/bcm47xx/board.c | 4 +-
arch/mips/bcm63xx/boards/board_bcm963xx.c | 2 +-
arch/powerpc/perf/imc-pmu.c | 2 +-
crypto/essiv.c | 2 +-
.../firmware/efi/libstub/efi-stub-helper.c | 2 +-
drivers/firmware/efi/libstub/gop.c | 10 ++--
drivers/gpu/drm/omapdrm/dss/base.c | 2 +-
.../gpu/drm/renesas/rcar-du/rcar_du_crtc.c | 2 +-
drivers/hid/hid-uclogic-params.c | 2 +-
drivers/input/mouse/psmouse-base.c | 2 +-
drivers/input/mouse/trackpoint.c | 2 +-
drivers/md/dm-crypt.c | 4 +-
drivers/memory/tegra/tegra20.c | 4 +-
drivers/mtd/spi-nor/issi.c | 2 +-
drivers/net/ethernet/intel/ice/ice_parser.c | 10 ++--
drivers/of/property.c | 2 +-
drivers/pci/pwrctrl/core.c | 2 +-
drivers/platform/x86/acerhdf.c | 6 +--
drivers/platform/x86/dell/dell-lis3lv02d.c | 2 +-
.../x86/hp/hp-bioscfg/spmobj-attributes.c | 4 +-
drivers/platform/x86/lenovo/thinkpad_acpi.c | 54 +++++++++----------
drivers/platform/x86/touchscreen_dmi.c | 2 +-
drivers/remoteproc/imx_dsp_rproc.c | 2 +-
drivers/remoteproc/imx_rproc.c | 8 +--
drivers/remoteproc/st_remoteproc.c | 2 +-
drivers/remoteproc/stm32_rproc.c | 2 +-
drivers/remoteproc/xlnx_r5_remoteproc.c | 2 +-
drivers/usb/dwc3/dwc3-pci.c | 2 +-
drivers/usb/musb/musb_cppi41.c | 4 +-
drivers/usb/musb/musb_debugfs.c | 20 +++----
fs/smb/client/reparse.c | 14 ++---
init/main.c | 2 +-
kernel/module/kallsyms.c | 2 +-
kernel/module/main.c | 8 +--
.../hda/codecs/side-codecs/tas2781_hda_i2c.c | 6 +--
36 files changed, 105 insertions(+), 105 deletions(-)
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 55ca3fcd37e8..91af37789ecb 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -22,16 +22,16 @@
bool module_init_section(const char *name)
{
- return strstarts(name, ".init") ||
- strstarts(name, ".ARM.extab.init") ||
- strstarts(name, ".ARM.exidx.init");
+ return strprefix(name, ".init") ||
+ strprefix(name, ".ARM.extab.init") ||
+ strprefix(name, ".ARM.exidx.init");
}
bool module_exit_section(const char *name)
{
- return strstarts(name, ".exit") ||
- strstarts(name, ".ARM.extab.exit") ||
- strstarts(name, ".ARM.exidx.exit");
+ return strprefix(name, ".exit") ||
+ strprefix(name, ".ARM.extab.exit") ||
+ strprefix(name, ".ARM.exidx.exit");
}
#ifdef CONFIG_ARM_HAS_GROUP_RELOCS
diff --git a/arch/mips/bcm47xx/board.c b/arch/mips/bcm47xx/board.c
index b487f687f62d..25fa1ef36ce8 100644
--- a/arch/mips/bcm47xx/board.c
+++ b/arch/mips/bcm47xx/board.c
@@ -251,7 +251,7 @@ static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void)
if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0) {
for (e1 = bcm47xx_board_list_hardware_version; e1->value1; e1++) {
- if (strstarts(buf1, e1->value1))
+ if (strprefix(buf1, e1->value1))
return &e1->board;
}
}
@@ -259,7 +259,7 @@ static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void)
if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0 &&
bcm47xx_nvram_getenv("boardnum", buf2, sizeof(buf2)) >= 0) {
for (e2 = bcm47xx_board_list_hw_version_num; e2->value1; e2++) {
- if (!strstarts(buf1, e2->value1) &&
+ if (!strprefix(buf1, e2->value1) &&
!strcmp(buf2, e2->value2))
return &e2->board;
}
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index 71628dac6c26..8083aeaab5b5 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -748,7 +748,7 @@ void __init board_prom_init(void)
/* dump cfe version */
cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET;
- if (strstarts(cfe, "cfe-")) {
+ if (strprefix(cfe, "cfe-")) {
if(cfe[4] == 'v') {
if(cfe[5] == 'd')
snprintf(cfe_version, 11, "%s",
diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index a9f8464997a2..aff88b1fd3cf 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -1023,7 +1023,7 @@ static int thread_imc_event_init(struct perf_event *event)
static bool is_thread_imc_pmu(struct perf_event *event)
{
- return strstarts(event->pmu->name, "thread_imc");
+ return strprefix(event->pmu->name, "thread_imc");
}
static __be64 *get_event_base_addr(struct perf_event *event)
diff --git a/crypto/essiv.c b/crypto/essiv.c
index a47a3eab6935..ee1bba6a48ce 100644
--- a/crypto/essiv.c
+++ b/crypto/essiv.c
@@ -508,7 +508,7 @@ static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
goto out_free_inst;
aead_alg = crypto_spawn_aead_alg(&ictx->u.aead_spawn);
block_base = &aead_alg->base;
- if (!strstarts(block_base->cra_name, "authenc(")) {
+ if (!strprefix(block_base->cra_name, "authenc(")) {
pr_warn("Only authenc() type AEADs are supported by ESSIV\n");
err = -EINVAL;
goto out_drop_skcipher;
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index 8e43eb3f418b..fbd0dda856b8 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -104,7 +104,7 @@ efi_status_t efi_parse_options(char const *cmdline)
if (parse_option_str(val, "debug"))
efi_loglevel = CONSOLE_LOGLEVEL_DEBUG;
} else if (!strcmp(param, "video") &&
- val && strstarts(val, "efifb:")) {
+ val && strprefix(val, "efifb:")) {
efi_parse_option_graphics(val + strlen("efifb:"));
}
}
diff --git a/drivers/firmware/efi/libstub/gop.c b/drivers/firmware/efi/libstub/gop.c
index b800a6c2290c..c1cbf2b91867 100644
--- a/drivers/firmware/efi/libstub/gop.c
+++ b/drivers/firmware/efi/libstub/gop.c
@@ -42,7 +42,7 @@ static bool parse_modenum(char *option, char **next)
{
u32 m;
- if (!strstarts(option, "mode="))
+ if (!strprefix(option, "mode="))
return false;
option += strlen("mode=");
m = simple_strtoull(option, &option, 0);
@@ -68,10 +68,10 @@ static bool parse_res(char *option, char **next)
h = simple_strtoull(option, &option, 10);
if (*option == '-') {
option++;
- if (strstarts(option, "rgb")) {
+ if (strprefix(option, "rgb")) {
option += strlen("rgb");
pf = PIXEL_RGB_RESERVED_8BIT_PER_COLOR;
- } else if (strstarts(option, "bgr")) {
+ } else if (strprefix(option, "bgr")) {
option += strlen("bgr");
pf = PIXEL_BGR_RESERVED_8BIT_PER_COLOR;
} else if (isdigit(*option))
@@ -93,7 +93,7 @@ static bool parse_res(char *option, char **next)
static bool parse_auto(char *option, char **next)
{
- if (!strstarts(option, "auto"))
+ if (!strprefix(option, "auto"))
return false;
option += strlen("auto");
if (*option && *option++ != ',')
@@ -106,7 +106,7 @@ static bool parse_auto(char *option, char **next)
static bool parse_list(char *option, char **next)
{
- if (!strstarts(option, "list"))
+ if (!strprefix(option, "list"))
return false;
option += strlen("list");
if (*option && *option++ != ',')
diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c
index a4ac113e1690..4179a89a4395 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -260,7 +260,7 @@ static bool omapdss_component_is_loaded(struct omapdss_comp_node *comp)
{
if (comp->dss_core_component)
return true;
- if (!strstarts(comp->compat, "omapdss,"))
+ if (!strprefix(comp->compat, "omapdss,"))
return true;
if (omapdss_device_is_registered(comp->node))
return true;
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.c
index 59c2a4b76137..60aa8720f622 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.c
@@ -1051,7 +1051,7 @@ static int rcar_du_crtc_parse_crc_source(struct rcar_du_crtc *rcrtc,
} else if (!strcmp(source_name, "auto")) {
*source = VSP1_DU_CRC_OUTPUT;
return 0;
- } else if (strstarts(source_name, "plane")) {
+ } else if (strprefix(source_name, "plane")) {
unsigned int i;
*source = VSP1_DU_CRC_PLANE;
diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c
index ed16f50f21ed..fc8297d76a3c 100644
--- a/drivers/hid/hid-uclogic-params.c
+++ b/drivers/hid/hid-uclogic-params.c
@@ -1270,7 +1270,7 @@ static bool uclogic_params_ugee_v2_has_battery(struct hid_device *hdev)
hdev->product == USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L) {
struct usb_device *udev = hid_to_usb_dev(hdev);
- if (strstarts(udev->product, "Deco LW"))
+ if (strprefix(udev->product, "Deco LW"))
return true;
}
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 23164688210d..3f5556227acb 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -513,7 +513,7 @@ bool psmouse_matches_pnp_id(struct psmouse *psmouse, const char * const ids[])
struct serio *serio = psmouse->ps2dev.serio;
const char *p = serio->firmware_id;
- if (!strstarts(p, "PNP: "))
+ if (!strprefix(p, "PNP: "))
return false;
p += 5;
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index 3bd8fdf56cd3..b7fc22ffd174 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -418,7 +418,7 @@ static bool trackpoint_is_dt_capable(const char *pnp_id)
return false;
/* Must start with "PNP: LEN03" */
- if (!strstarts(pnp_id, "PNP: LEN03"))
+ if (!strprefix(pnp_id, "PNP: LEN03"))
return false;
/* Ensure enough length before comparing */
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index a7655bba7ce3..e3ce3880f3f1 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -2847,7 +2847,7 @@ static int crypt_ctr_auth_cipher(struct crypt_config *cc, char *cipher_api)
char *start, *end, *mac_alg = NULL;
struct crypto_ahash *mac;
- if (!strstarts(cipher_api, "authenc("))
+ if (!strprefix(cipher_api, "authenc("))
return 0;
start = strchr(cipher_api, '(');
@@ -3051,7 +3051,7 @@ static int crypt_ctr_cipher(struct dm_target *ti, char *cipher_in, char *key)
return -ENOMEM;
}
- if (strstarts(cipher_in, "capi:"))
+ if (strprefix(cipher_in, "capi:"))
ret = crypt_ctr_cipher_new(ti, cipher_in, key, &ivmode, &ivopts);
else
ret = crypt_ctr_cipher_old(ti, cipher_in, key, &ivmode, &ivopts);
diff --git a/drivers/memory/tegra/tegra20.c b/drivers/memory/tegra/tegra20.c
index 27dd6886f86e..edb4d10ae36d 100644
--- a/drivers/memory/tegra/tegra20.c
+++ b/drivers/memory/tegra/tegra20.c
@@ -408,8 +408,8 @@ tegra20_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
ndata->node = node;
/* these clients are isochronous by default */
- if (strstarts(node->name, "display") ||
- strstarts(node->name, "vi"))
+ if (strprefix(node->name, "display") ||
+ strprefix(node->name, "vi"))
ndata->tag = TEGRA_MC_ICC_TAG_ISO;
else
ndata->tag = TEGRA_MC_ICC_TAG_DEFAULT;
diff --git a/drivers/mtd/spi-nor/issi.c b/drivers/mtd/spi-nor/issi.c
index 2f057d731df2..7fb8fc7b6b8f 100644
--- a/drivers/mtd/spi-nor/issi.c
+++ b/drivers/mtd/spi-nor/issi.c
@@ -138,7 +138,7 @@ static bool issi_pm25lv_match(const struct spi_nor *nor)
{
const char *name = nor->info ? nor->info->name : NULL;
- return name && strstarts(name, "pm25lv");
+ return name && strprefix(name, "pm25lv");
}
static const struct spi_nor_fixup issi_fixup_list[] = {
diff --git a/drivers/net/ethernet/intel/ice/ice_parser.c b/drivers/net/ethernet/intel/ice/ice_parser.c
index d239102c52ff..0db6407d7453 100644
--- a/drivers/net/ethernet/intel/ice/ice_parser.c
+++ b/drivers/net/ethernet/intel/ice/ice_parser.c
@@ -1375,15 +1375,15 @@ static void ice_parse_lbl_item(struct ice_hw *hw, u16 idx, void *item,
lbl_item->idx = lbl_data->idx;
memcpy(lbl_item->label, lbl_data->label, sizeof(lbl_item->label));
- if (strstarts(lbl_item->label, ICE_LBL_BST_DVM))
+ if (strprefix(lbl_item->label, ICE_LBL_BST_DVM))
lbl_item->type = ICE_LBL_BST_TYPE_DVM;
- else if (strstarts(lbl_item->label, ICE_LBL_BST_SVM))
+ else if (strprefix(lbl_item->label, ICE_LBL_BST_SVM))
lbl_item->type = ICE_LBL_BST_TYPE_SVM;
- else if (strstarts(lbl_item->label, ICE_LBL_TNL_VXLAN))
+ else if (strprefix(lbl_item->label, ICE_LBL_TNL_VXLAN))
lbl_item->type = ICE_LBL_BST_TYPE_VXLAN;
- else if (strstarts(lbl_item->label, ICE_LBL_TNL_GENEVE))
+ else if (strprefix(lbl_item->label, ICE_LBL_TNL_GENEVE))
lbl_item->type = ICE_LBL_BST_TYPE_GENEVE;
- else if (strstarts(lbl_item->label, ICE_LBL_TNL_UDP_ECPRI))
+ else if (strprefix(lbl_item->label, ICE_LBL_TNL_UDP_ECPRI))
lbl_item->type = ICE_LBL_BST_TYPE_UDP_ECPRI;
if (hw->debug_mask & ICE_DBG_PARSER)
diff --git a/drivers/of/property.c b/drivers/of/property.c
index 45e55f618488..f0729619a2a0 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -1421,7 +1421,7 @@ DEFINE_SUFFIX_PROP(gpio, "-gpio", "#gpio-cells")
static struct device_node *parse_pinctrl_n(struct device_node *np,
const char *prop_name, int index)
{
- if (!strstarts(prop_name, "pinctrl-"))
+ if (!strprefix(prop_name, "pinctrl-"))
return NULL;
if (!isdigit(prop_name[strlen("pinctrl-")]))
diff --git a/drivers/pci/pwrctrl/core.c b/drivers/pci/pwrctrl/core.c
index 0e2387cf4657..4544352d39c0 100644
--- a/drivers/pci/pwrctrl/core.c
+++ b/drivers/pci/pwrctrl/core.c
@@ -159,7 +159,7 @@ static bool pci_pwrctrl_is_required(struct device_node *np)
if (ret < 0)
return false;
- if (!strstarts(compat, "pci"))
+ if (!strprefix(compat, "pci"))
return false;
if (of_pci_supply_present(np))
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index 5ce5ad3efe69..25540b169339 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -582,9 +582,9 @@ static int __init acerhdf_check_hardware(void)
* check if actual hardware BIOS vendor, product and version
* IDs start with the strings of BIOS table entry
*/
- if (strstarts(vendor, bt->vendor) &&
- strstarts(product, bt->product) &&
- strstarts(version, bt->version)) {
+ if (strprefix(vendor, bt->vendor) &&
+ strprefix(product, bt->product) &&
+ strprefix(version, bt->version)) {
found = 1;
break;
}
diff --git a/drivers/platform/x86/dell/dell-lis3lv02d.c b/drivers/platform/x86/dell/dell-lis3lv02d.c
index fe52bcd896f7..8ff52a7a9242 100644
--- a/drivers/platform/x86/dell/dell-lis3lv02d.c
+++ b/drivers/platform/x86/dell/dell-lis3lv02d.c
@@ -106,7 +106,7 @@ static bool i2c_adapter_is_main_i801(struct i2c_adapter *adap)
* Only match the main I801 adapter and reject secondary adapters
* which names start with "SMBus I801 IDF adapter".
*/
- return strstarts(adap->name, "SMBus I801 adapter");
+ return strprefix(adap->name, "SMBus I801 adapter");
}
static int find_i801(struct device *dev, void *data)
diff --git a/drivers/platform/x86/hp/hp-bioscfg/spmobj-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/spmobj-attributes.c
index a38d200bd0d9..dd50581a1572 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/spmobj-attributes.c
+++ b/drivers/platform/x86/hp/hp-bioscfg/spmobj-attributes.c
@@ -49,7 +49,7 @@ size_t hp_calculate_security_buffer(const char *authentication)
authlen = strlen(authentication);
size = sizeof(u16) + authlen * sizeof(u16);
- if (!strstarts(authentication, BEAM_PREFIX))
+ if (!strprefix(authentication, BEAM_PREFIX))
size += strlen(UTF_PREFIX) * sizeof(u16);
return size;
@@ -70,7 +70,7 @@ int hp_populate_security_buffer(u16 *authbuf, const char *authentication)
char *prefix = NULL;
int ret = 0;
- if (strstarts(authentication, BEAM_PREFIX)) {
+ if (strprefix(authentication, BEAM_PREFIX)) {
/*
* BEAM_PREFIX is append to authbuf when a signature
* is provided and Sure Admin is enabled in BIOS
diff --git a/drivers/platform/x86/lenovo/thinkpad_acpi.c b/drivers/platform/x86/lenovo/thinkpad_acpi.c
index 4f81855ad721..293ef2e2c9a5 100644
--- a/drivers/platform/x86/lenovo/thinkpad_acpi.c
+++ b/drivers/platform/x86/lenovo/thinkpad_acpi.c
@@ -1311,9 +1311,9 @@ static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf)
return -ENODEV;
while ((cmd = strsep(&buf, ","))) {
- if (strstarts(cmd, "enable"))
+ if (strprefix(cmd, "enable"))
status = TPACPI_RFK_RADIO_ON;
- else if (strstarts(cmd, "disable"))
+ else if (strprefix(cmd, "disable"))
status = TPACPI_RFK_RADIO_OFF;
else
return -EINVAL;
@@ -4119,12 +4119,12 @@ static int hotkey_write(char *buf)
res = 0;
while ((cmd = strsep(&buf, ","))) {
- if (strstarts(cmd, "enable")) {
+ if (strprefix(cmd, "enable")) {
hotkey_enabledisable_warn(1);
- } else if (strstarts(cmd, "disable")) {
+ } else if (strprefix(cmd, "disable")) {
hotkey_enabledisable_warn(0);
res = -EPERM;
- } else if (strstarts(cmd, "reset")) {
+ } else if (strprefix(cmd, "reset")) {
mask = (hotkey_all_mask | hotkey_source_mask)
& ~hotkey_reserved_mask;
} else if (sscanf(cmd, "0x%x", &mask) == 1) {
@@ -5043,33 +5043,33 @@ static int video_write(char *buf)
disable = 0;
while ((cmd = strsep(&buf, ","))) {
- if (strstarts(cmd, "lcd_enable")) {
+ if (strprefix(cmd, "lcd_enable")) {
enable |= TP_ACPI_VIDEO_S_LCD;
- } else if (strstarts(cmd, "lcd_disable")) {
+ } else if (strprefix(cmd, "lcd_disable")) {
disable |= TP_ACPI_VIDEO_S_LCD;
- } else if (strstarts(cmd, "crt_enable")) {
+ } else if (strprefix(cmd, "crt_enable")) {
enable |= TP_ACPI_VIDEO_S_CRT;
- } else if (strstarts(cmd, "crt_disable")) {
+ } else if (strprefix(cmd, "crt_disable")) {
disable |= TP_ACPI_VIDEO_S_CRT;
} else if (video_supported == TPACPI_VIDEO_NEW &&
- strstarts(cmd, "dvi_enable")) {
+ strprefix(cmd, "dvi_enable")) {
enable |= TP_ACPI_VIDEO_S_DVI;
} else if (video_supported == TPACPI_VIDEO_NEW &&
- strstarts(cmd, "dvi_disable")) {
+ strprefix(cmd, "dvi_disable")) {
disable |= TP_ACPI_VIDEO_S_DVI;
- } else if (strstarts(cmd, "auto_enable")) {
+ } else if (strprefix(cmd, "auto_enable")) {
res = video_autosw_set(1);
if (res)
return res;
- } else if (strstarts(cmd, "auto_disable")) {
+ } else if (strprefix(cmd, "auto_disable")) {
res = video_autosw_set(0);
if (res)
return res;
- } else if (strstarts(cmd, "video_switch")) {
+ } else if (strprefix(cmd, "video_switch")) {
res = video_outputsw_cycle();
if (res)
return res;
- } else if (strstarts(cmd, "expand_toggle")) {
+ } else if (strprefix(cmd, "expand_toggle")) {
res = video_expand_toggle();
if (res)
return res;
@@ -5458,9 +5458,9 @@ static int light_write(char *buf)
return -ENODEV;
while ((cmd = strsep(&buf, ","))) {
- if (strstarts(cmd, "on")) {
+ if (strprefix(cmd, "on")) {
newstatus = 1;
- } else if (strstarts(cmd, "off")) {
+ } else if (strprefix(cmd, "off")) {
newstatus = 0;
} else
return -EINVAL;
@@ -6983,10 +6983,10 @@ static int brightness_write(char *buf)
return level;
while ((cmd = strsep(&buf, ","))) {
- if (strstarts(cmd, "up")) {
+ if (strprefix(cmd, "up")) {
if (level < bright_maxlvl)
level++;
- } else if (strstarts(cmd, "down")) {
+ } else if (strprefix(cmd, "down")) {
if (level > 0)
level--;
} else if (sscanf(cmd, "level %d", &level) == 1 &&
@@ -7731,13 +7731,13 @@ static int volume_write(char *buf)
while ((cmd = strsep(&buf, ","))) {
if (!tp_features.mixer_no_level_control) {
- if (strstarts(cmd, "up")) {
+ if (strprefix(cmd, "up")) {
if (new_mute)
new_mute = 0;
else if (new_level < TP_EC_VOLUME_MAX)
new_level++;
continue;
- } else if (strstarts(cmd, "down")) {
+ } else if (strprefix(cmd, "down")) {
if (new_mute)
new_mute = 0;
else if (new_level > 0)
@@ -7749,9 +7749,9 @@ static int volume_write(char *buf)
continue;
}
}
- if (strstarts(cmd, "mute"))
+ if (strprefix(cmd, "mute"))
new_mute = TP_EC_AUDIO_MUTESW_MSK;
- else if (strstarts(cmd, "unmute"))
+ else if (strprefix(cmd, "unmute"))
new_mute = 0;
else
return -EINVAL;
@@ -9245,9 +9245,9 @@ static int fan_write_cmd_level(const char *cmd, int *rc)
{
int level;
- if (strstarts(cmd, "level auto"))
+ if (strprefix(cmd, "level auto"))
level = TP_EC_FAN_AUTO;
- else if (strstarts(cmd, "level disengaged") || strstarts(cmd, "level full-speed"))
+ else if (strprefix(cmd, "level disengaged") || strprefix(cmd, "level full-speed"))
level = TP_EC_FAN_FULLSPEED;
else if (sscanf(cmd, "level %d", &level) != 1)
return 0;
@@ -9265,7 +9265,7 @@ static int fan_write_cmd_level(const char *cmd, int *rc)
static int fan_write_cmd_enable(const char *cmd, int *rc)
{
- if (!strstarts(cmd, "enable"))
+ if (!strprefix(cmd, "enable"))
return 0;
*rc = fan_set_enable();
@@ -9280,7 +9280,7 @@ static int fan_write_cmd_enable(const char *cmd, int *rc)
static int fan_write_cmd_disable(const char *cmd, int *rc)
{
- if (!strstarts(cmd, "disable"))
+ if (!strprefix(cmd, "disable"))
return 0;
*rc = fan_set_disable();
diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c
index d83c387821ea..72f18dfc4368 100644
--- a/drivers/platform/x86/touchscreen_dmi.c
+++ b/drivers/platform/x86/touchscreen_dmi.c
@@ -1877,7 +1877,7 @@ static void ts_dmi_add_props(struct i2c_client *client)
int error;
if (has_acpi_companion(dev) &&
- strstarts(client->name, ts_data->acpi_name)) {
+ strprefix(client->name, ts_data->acpi_name)) {
error = device_create_managed_software_node(dev, ts_data->properties, NULL);
if (error)
dev_err(dev, "failed to add properties: %d\n", error);
diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c
index 96d619daf3f5..8e8085f27a64 100644
--- a/drivers/remoteproc/imx_dsp_rproc.c
+++ b/drivers/remoteproc/imx_dsp_rproc.c
@@ -699,7 +699,7 @@ static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv)
* Ignore the first memory region which will be used vdev buffer.
* No need to do extra handlings, rproc_add_virtio_dev will handle it.
*/
- if (strstarts(res.name, "vdev0buffer"))
+ if (strprefix(res.name, "vdev0buffer"))
continue;
if (imx_dsp_rproc_sys_to_da(priv, res.start, resource_size(&res), &da))
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 581bb07f5893..9f39e1a10f99 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -656,10 +656,10 @@ static int imx_rproc_prepare(struct rproc *rproc)
* Ignore the first memory region which will be used vdev buffer.
* No need to do extra handlings, rproc_add_virtio_dev will handle it.
*/
- if (strstarts(res.name, "vdev0buffer"))
+ if (strprefix(res.name, "vdev0buffer"))
continue;
- if (strstarts(res.name, "rsc-table"))
+ if (strprefix(res.name, "rsc-table"))
continue;
/* No need to translate pa to da, i.MX use same map */
@@ -834,7 +834,7 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
}
/* Not map vdevbuffer, vdevring region */
- if (strstarts(res.name, "vdev"))
+ if (strprefix(res.name, "vdev"))
continue;
if (b >= IMX_RPROC_MEM_MAX)
@@ -848,7 +848,7 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
}
priv->mem[b].sys_addr = res.start;
priv->mem[b].size = resource_size(&res);
- if (strstarts(res.name, "rsc-table"))
+ if (strprefix(res.name, "rsc-table"))
priv->rsc_table = priv->mem[b].cpu_addr;
b++;
}
diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c
index 486180cdccb4..3a351313b0c1 100644
--- a/drivers/remoteproc/st_remoteproc.c
+++ b/drivers/remoteproc/st_remoteproc.c
@@ -106,7 +106,7 @@ static int st_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
return ret;
/* No need to map vdev buffer */
- if (!strstarts(res.name, "vdev0buffer")) {
+ if (!strprefix(res.name, "vdev0buffer")) {
/* Register memory region */
mem = rproc_mem_entry_init(dev, NULL,
(dma_addr_t)res.start,
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index a47e040c6db8..254ebc820721 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -203,7 +203,7 @@ static int stm32_rproc_prepare(struct rproc *rproc)
}
/* No need to map vdev buffer */
- if (!strstarts(res.name, "vdev0buffer")) {
+ if (!strprefix(res.name, "vdev0buffer")) {
/* Register memory region */
mem = rproc_mem_entry_init(dev, NULL,
(dma_addr_t)res.start,
diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
index a9873a37dd8f..6b2eaa221334 100644
--- a/drivers/remoteproc/xlnx_r5_remoteproc.c
+++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
@@ -471,7 +471,7 @@ static int add_mem_regions_carveout(struct rproc *rproc)
if (err)
return 0;
- if (strstarts(res.name, "vdev0buffer")) {
+ if (strprefix(res.name, "vdev0buffer")) {
/* Init reserved memory for vdev buffer */
rproc_mem = rproc_of_resm_mem_entry_init(&rproc->dev, i,
resource_size(&res),
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 6c1cbb722ca8..21e6e14ced31 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -301,7 +301,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc,
acpi_quirk_skip_acpi_ac_and_battery() &&
/* Lenovo Yoga Tablet 2 Pro 1380 uses LC824206XA instead */
!(bios_ver &&
- strstarts(bios_ver, "BLADE_21.X64.0005.R00.1504101516"))) {
+ strprefix(bios_ver, "BLADE_21.X64.0005.R00.1504101516"))) {
dev_info(&pdev->dev, "Using TUSB1211 phy for charger detection\n");
swnode = &dwc3_pci_intel_phy_charger_detect_swnode;
}
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
index 28e958fcc862..c0786ad5a97f 100644
--- a/drivers/usb/musb/musb_cppi41.c
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -686,9 +686,9 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
ret = of_property_read_string_index(np, "dma-names", i, &str);
if (ret)
goto err;
- if (strstarts(str, "tx"))
+ if (strprefix(str, "tx"))
is_tx = 1;
- else if (strstarts(str, "rx"))
+ else if (strprefix(str, "rx"))
is_tx = 0;
else {
dev_err(dev, "Wrong dmatype %s\n", str);
diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c
index 5092d62c2062..97cf89c6e451 100644
--- a/drivers/usb/musb/musb_debugfs.c
+++ b/drivers/usb/musb/musb_debugfs.c
@@ -179,36 +179,36 @@ static ssize_t musb_test_mode_write(struct file *file,
goto ret;
}
- if (strstarts(buf, "force host full-speed"))
+ if (strprefix(buf, "force host full-speed"))
test = MUSB_TEST_FORCE_HOST | MUSB_TEST_FORCE_FS;
- else if (strstarts(buf, "force host high-speed"))
+ else if (strprefix(buf, "force host high-speed"))
test = MUSB_TEST_FORCE_HOST | MUSB_TEST_FORCE_HS;
- else if (strstarts(buf, "force host"))
+ else if (strprefix(buf, "force host"))
test = MUSB_TEST_FORCE_HOST;
- else if (strstarts(buf, "fifo access"))
+ else if (strprefix(buf, "fifo access"))
test = MUSB_TEST_FIFO_ACCESS;
- else if (strstarts(buf, "force full-speed"))
+ else if (strprefix(buf, "force full-speed"))
test = MUSB_TEST_FORCE_FS;
- else if (strstarts(buf, "force high-speed"))
+ else if (strprefix(buf, "force high-speed"))
test = MUSB_TEST_FORCE_HS;
- else if (strstarts(buf, "test packet")) {
+ else if (strprefix(buf, "test packet")) {
test = MUSB_TEST_PACKET;
musb_load_testpacket(musb);
}
- else if (strstarts(buf, "test K"))
+ else if (strprefix(buf, "test K"))
test = MUSB_TEST_K;
- else if (strstarts(buf, "test J"))
+ else if (strprefix(buf, "test J"))
test = MUSB_TEST_J;
- else if (strstarts(buf, "test SE0 NAK"))
+ else if (strprefix(buf, "test SE0 NAK"))
test = MUSB_TEST_SE0_NAK;
musb_writeb(musb->mregs, MUSB_TESTMODE, test);
diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c
index 3a27773186ae..d35af97cdbad 100644
--- a/fs/smb/client/reparse.c
+++ b/fs/smb/client/reparse.c
@@ -97,7 +97,7 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode,
* ensure compatibility of this symlink stored in absolute form
* on the SMB server.
*/
- if (!strstarts(symname, symroot)) {
+ if (!strprefix(symname, symroot)) {
/*
* If the absolute Linux symlink target path is not
* inside "symlinkroot" location then there is no way
@@ -171,7 +171,7 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode,
* letter so the prefix occupies six characters in UTF-16 too.
*/
if (!(sbflags & CIFS_MOUNT_POSIX_PATHS) && symname[0] == '/') {
- if (!strstarts(sym, "\\??\\") || !isascii(sym[4]) ||
+ if (!strprefix(sym, "\\??\\") || !isascii(sym[4]) ||
!isalpha(sym[4]) || sym[5] != ':') {
rc = -EINVAL;
goto out;
@@ -905,11 +905,11 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
*/
abs_path = smb_target;
globalroot:
- if (strstarts(abs_path, "\\??\\"))
+ if (strprefix(abs_path, "\\??\\"))
abs_path += sizeof("\\??\\")-1;
- else if (strstarts(abs_path, "\\DosDevices\\"))
+ else if (strprefix(abs_path, "\\DosDevices\\"))
abs_path += sizeof("\\DosDevices\\")-1;
- else if (strstarts(abs_path, "\\GLOBAL??\\"))
+ else if (strprefix(abs_path, "\\GLOBAL??\\"))
abs_path += sizeof("\\GLOBAL??\\")-1;
else
goto out_unhandled_target;
@@ -918,10 +918,10 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
if (abs_path[0] == '\\')
abs_path++;
- while (strstarts(abs_path, "Global\\"))
+ while (strprefix(abs_path, "Global\\"))
abs_path += sizeof("Global\\")-1;
- if (strstarts(abs_path, "GLOBALROOT\\")) {
+ if (strprefix(abs_path, "GLOBALROOT\\")) {
/* Label globalroot requires path with leading '\\', so do not trim '\\' */
abs_path += sizeof("GLOBALROOT")-1;
goto globalroot;
diff --git a/init/main.c b/init/main.c
index 7b0c8c34e6a9..44513443d127 100644
--- a/init/main.c
+++ b/init/main.c
@@ -586,7 +586,7 @@ static int __init unknown_bootoption(char *param, char *val,
/* Handle bootloader identifier */
for (int i = 0; bootloader[i]; i++) {
- if (strstarts(param, bootloader[i]))
+ if (strprefix(param, bootloader[i]))
return 0;
}
diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c
index 1ff8ce857d92..bcdf2ebe0d32 100644
--- a/kernel/module/kallsyms.c
+++ b/kernel/module/kallsyms.c
@@ -68,7 +68,7 @@ static char elf_type(const Elf_Sym *sym, const struct load_info *info)
else
return 'b';
}
- if (strstarts(info->secstrings + sechdrs[sym->st_shndx].sh_name,
+ if (strprefix(info->secstrings + sechdrs[sym->st_shndx].sh_name,
".debug")) {
return 'n';
}
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 34e0204ea37c..d97502225b3d 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -1195,7 +1195,7 @@ static bool verify_module_namespace(const char *namespace, const char *modname)
const char *sep;
bool glob;
- if (!strstarts(namespace, prefix))
+ if (!strprefix(namespace, prefix))
return false;
for (namespace += strlen(prefix); *namespace; namespace = sep) {
@@ -1836,7 +1836,7 @@ static int setup_modinfo(struct module *mod, struct load_info *info)
* 'module:' prefixed namespaces are implicit, disallow
* explicit imports.
*/
- if (strstarts(imported_namespace, "module:")) {
+ if (strprefix(imported_namespace, "module:")) {
pr_err("%s: module tries to import module namespace: %s\n",
mod->name, imported_namespace);
return -EPERM;
@@ -1863,12 +1863,12 @@ static void free_modinfo(struct module *mod)
bool __weak module_init_section(const char *name)
{
- return strstarts(name, ".init");
+ return strprefix(name, ".init");
}
bool __weak module_exit_section(const char *name)
{
- return strstarts(name, ".exit");
+ return strprefix(name, ".exit");
}
static int validate_section_offset(const struct load_info *info, Elf_Shdr *shdr)
diff --git a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c
index 0c8faa583baa..bf24dce50e23 100644
--- a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c
+++ b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c
@@ -636,14 +636,14 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt)
tas_hda->priv->chip_id = TAS2781;
hda_priv->save_calibration = tas2781_save_calibration;
tas_hda->priv->global_addr = TAS2781_GLOBAL_ADDR;
- } else if (strstarts(dev_name(&clt->dev), "i2c-TXNW2770")) {
+ } else if (strprefix(dev_name(&clt->dev), "i2c-TXNW2770")) {
/*
* TAS2770, has no on-chip DSP, so no calibration data
* required; has no global I2C address supported.
*/
device_name = "TXNW2770";
hda_priv->hda_chip_id = HDA_TAS2770;
- } else if (strstarts(dev_name(&clt->dev),
+ } else if (strprefix(dev_name(&clt->dev),
"i2c-TXNW2781:00-tas2781-hda.0")) {
device_name = "TXNW2781";
hda_priv->hda_chip_id = HDA_TAS2781;
@@ -659,7 +659,7 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt)
hda_priv->hda_chip_id = HDA_TAS2563;
hda_priv->save_calibration = tas2563_save_calibration;
tas_hda->priv->global_addr = TAS2563_GLOBAL_ADDR;
- } else if (strstarts(dev_name(&clt->dev), "i2c-TXNW5825")) {
+ } else if (strprefix(dev_name(&clt->dev), "i2c-TXNW5825")) {
/*
* TAS5825, integrated on-chip DSP without
* global I2C address and calibration supported.
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v6 12/19] string: Remove strstarts()
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (10 preceding siblings ...)
2026-11-14 15:23 ` [PATCH v6 11/19] treewide: s/strstarts/strprefix/g Alejandro Colomar
@ 2026-11-14 15:23 ` Alejandro Colomar
2026-11-14 15:29 ` sashiko-bot
2026-11-14 15:23 ` [PATCH v6 13/19] s390/test_unwind: Use bool for booleans Alejandro Colomar
` (6 subsequent siblings)
18 siblings, 1 reply; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:23 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio
[-- Attachment #1: Type: text/plain, Size: 722 bytes --]
It's now unused, as it's been fully replaced by strprefix().
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
include/linux/string.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/include/linux/string.h b/include/linux/string.h
index 0a466360dbb3..6b0de932e23a 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -609,7 +609,6 @@ static inline const char *strprefix(const char *s, const char *prefix)
return strncmp(s, prefix, len) == 0 ? s + len : NULL;
}
#define strprefix(s, pfx) const_cast(CQChar_of(s) *, strprefix(s, pfx))
-#define strstarts(s, pfx) strprefix(s, pfx) // legacy alias
/**
* str_has_prefix - Test if a string has a given prefix
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v6 12/19] string: Remove strstarts()
2026-11-14 15:23 ` [PATCH v6 12/19] string: Remove strstarts() Alejandro Colomar
@ 2026-11-14 15:29 ` sashiko-bot
0 siblings, 0 replies; 24+ messages in thread
From: sashiko-bot @ 2026-11-14 15:29 UTC (permalink / raw)
To: Alejandro Colomar; +Cc: devicetree, linux-gpio, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [High] string: removing strstarts() breaks build in
xe_sysctrl_mailbox_write()
--
commit e1746880c54dd32f27fc7343468741cdc4b05246
Author: Alejandro Colomar <alx@kernel.org>
string: Remove strstarts()
This commit removes the legacy strstarts() macro alias for strprefix() from
include/linux/string.h.
> diff --git a/include/linux/string.h b/include/linux/string.h
> index 0a466360dbb39..6b0de932e23a8 100644
> --- a/include/linux/string.h
> +++ b/include/linux/string.h
> @@ -609,7 +609,6 @@ static inline const char *strprefix(const char *s, const char *prefix)
> return strncmp(s, prefix, len) == 0 ? s + len : NULL;
> }
> #define strprefix(s, pfx) const_cast(CQChar_of(s) *, strprefix(s, pfx))
> -#define strstarts(s, pfx) strprefix(s, pfx) // legacy alias
[Severity: High]
Does removing strstarts() break the build when CONFIG_DRM_XE is enabled?
drivers/gpu/drm/xe/xe_sysctrl_debugfs.c:xe_sysctrl_mailbox_write() still
calls strstarts(token, "timeout=") and strstarts(token, "resplen="), which
now fail with an implicit function declaration error.
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1794667407.git.alx@kernel.org?part=12
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v6 13/19] s390/test_unwind: Use bool for booleans
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (11 preceding siblings ...)
2026-11-14 15:23 ` [PATCH v6 12/19] string: Remove strstarts() Alejandro Colomar
@ 2026-11-14 15:23 ` Alejandro Colomar
2026-11-14 15:23 ` [PATCH v6 14/19] treewide: Replace boolean uses of str_has_prefix() by strprefix() Alejandro Colomar
` (5 subsequent siblings)
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:23 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio
[-- Attachment #1: Type: text/plain, Size: 1834 bytes --]
This is obviously good per se, but it will also allow using strprefix()
instead of str_has_prefix().
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
arch/s390/lib/test_unwind.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/arch/s390/lib/test_unwind.c b/arch/s390/lib/test_unwind.c
index 6bb3fa5bf925..bb47958f5aed 100644
--- a/arch/s390/lib/test_unwind.c
+++ b/arch/s390/lib/test_unwind.c
@@ -47,7 +47,8 @@ static void print_backtrace(char *bt)
static noinline int test_unwind(struct task_struct *task, struct pt_regs *regs,
unsigned long sp)
{
- int frame_count, prev_is_func2, seen_func2_func1, seen_arch_rethook_trampoline;
+ int frame_count;
+ bool prev_is_func2, seen_func2_func1, seen_arch_rethook_trampoline;
const int max_frames = 128;
struct unwind_state state;
size_t bt_pos = 0;
@@ -61,9 +62,9 @@ static noinline int test_unwind(struct task_struct *task, struct pt_regs *regs,
}
/* Unwind. */
frame_count = 0;
- prev_is_func2 = 0;
- seen_func2_func1 = 0;
- seen_arch_rethook_trampoline = 0;
+ prev_is_func2 = false;
+ seen_func2_func1 = false;
+ seen_arch_rethook_trampoline = false;
unwind_for_each_frame(&state, task, regs, sp) {
unsigned long addr = unwind_get_return_address(&state);
char sym[KSYM_SYMBOL_LEN];
@@ -87,10 +88,10 @@ static noinline int test_unwind(struct task_struct *task, struct pt_regs *regs,
}
frame_count += 1;
if (prev_is_func2 && str_has_prefix(sym, "unwindme_func1"))
- seen_func2_func1 = 1;
+ seen_func2_func1 = true;
prev_is_func2 = str_has_prefix(sym, "unwindme_func2");
if (str_has_prefix(sym, "arch_rethook_trampoline+0x0/"))
- seen_arch_rethook_trampoline = 1;
+ seen_arch_rethook_trampoline = true;
}
/* Check the results. */
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v6 14/19] treewide: Replace boolean uses of str_has_prefix() by strprefix()
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (12 preceding siblings ...)
2026-11-14 15:23 ` [PATCH v6 13/19] s390/test_unwind: Use bool for booleans Alejandro Colomar
@ 2026-11-14 15:23 ` Alejandro Colomar
2026-11-14 15:23 ` [PATCH v6 15/19] treewide: Replace some " Alejandro Colomar
` (4 subsequent siblings)
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:23 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio
[-- Attachment #1: Type: text/plain, Size: 26894 bytes --]
str_has_prefix() doesn't work well for empty prefixes (see link below),
so this might actually fix some bugs silently where the prefix is an
empty string.
Link: https://lore.kernel.org/linux-hardening/20261104-fwnode-for-each-prop-v1-1-6e28fe1c72c4@oss.qualcomm.com/
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
arch/alpha/kernel/setup.c | 2 +-
arch/parisc/kernel/setup.c | 2 +-
arch/powerpc/platforms/powernv/pci-ioda.c | 2 +-
arch/s390/kernel/early_printk.c | 2 +-
arch/s390/kernel/module.c | 6 ++---
arch/s390/kernel/setup.c | 4 ++--
arch/s390/lib/test_unwind.c | 6 ++---
drivers/gpio/gpio-aggregator.c | 2 +-
drivers/gpu/drm/xe/xe_configfs.c | 6 ++---
drivers/iio/pressure/hsc030pa.c | 2 +-
drivers/md/dm-inlinecrypt.c | 2 +-
drivers/media/i2c/ds90ub960.c | 2 +-
drivers/remoteproc/mtk_scp.c | 2 +-
.../media/atomisp/pci/atomisp_csi2_bridge.c | 2 +-
drivers/tty/serial/serial_base_bus.c | 4 ++--
kernel/debug/kdb/kdb_main.c | 2 +-
kernel/kcsan/debugfs.c | 2 +-
kernel/kcsan/report.c | 2 +-
kernel/kprobes.c | 4 ++--
kernel/locking/locktorture.c | 8 +++----
kernel/power/main.c | 2 +-
kernel/trace/trace_events.c | 2 +-
kernel/trace/trace_events_hist.c | 14 ++++++------
kernel/trace/trace_events_synth.c | 2 +-
kernel/trace/trace_events_user.c | 22 +++++++++----------
kernel/trace/trace_probe.c | 22 +++++++++----------
mm/arch_numa.c | 2 +-
mm/kfence/report.c | 14 ++++++------
sound/soc/sdw_utils/soc_sdw_senary_sdca.c | 2 +-
29 files changed, 73 insertions(+), 73 deletions(-)
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 4cbcfb1852d5..79e63580b419 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -452,7 +452,7 @@ setup_arch(char **cmdline_p)
#ifndef alpha_using_srm
/* Assume that we've booted from SRM if we haven't booted from MILO.
Detect the later by looking for "MILO" in the system serial nr. */
- alpha_using_srm = !str_has_prefix((const char *)hwrpb->ssn, "MILO");
+ alpha_using_srm = !strprefix((const char *)hwrpb->ssn, "MILO");
#endif
#ifndef alpha_using_qemu
/* Similarly, look for QEMU. */
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
index 4d3015a411d6..6cd1b65276b5 100644
--- a/arch/parisc/kernel/setup.c
+++ b/arch/parisc/kernel/setup.c
@@ -56,7 +56,7 @@ static void __init setup_cmdline(char **cmdline_p)
/* autodetect console type (if not done by palo yet) */
p = boot_command_line;
- if (!str_has_prefix(p, "console=") && !strstr(p, " console=")) {
+ if (!strprefix(p, "console=") && !strstr(p, " console=")) {
strlcat(p, " console=", COMMAND_LINE_SIZE);
if (PAGE0->mem_cons.cl_class == CL_DUPLEX)
strlcat(p, "ttyS0", COMMAND_LINE_SIZE);
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 728a5610d167..1cf0b4afe3df 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1629,7 +1629,7 @@ int64_t pnv_opal_pci_msi_eoi(struct irq_data *d)
*/
bool is_pnv_opal_msi(struct irq_chip *chip)
{
- return chip && chip->name && str_has_prefix(chip->name, "PNV-");
+ return chip && chip->name && strprefix(chip->name, "PNV-");
}
EXPORT_SYMBOL_GPL(is_pnv_opal_msi);
diff --git a/arch/s390/kernel/early_printk.c b/arch/s390/kernel/early_printk.c
index cefe020a3be3..095e282c1e06 100644
--- a/arch/s390/kernel/early_printk.c
+++ b/arch/s390/kernel/early_printk.c
@@ -36,7 +36,7 @@ static int __init setup_early_printk(char *buf)
if (early_console)
return 0;
/* Accept only "earlyprintk" and "earlyprintk=sclp" */
- if (buf && !str_has_prefix(buf, "sclp"))
+ if (buf && !strprefix(buf, "sclp"))
return 0;
register_early_console();
return 0;
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index 9d1f8a50f5a4..e9734d2b25f3 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -520,15 +520,15 @@ int module_finalize(const Elf_Ehdr *hdr,
apply_alternatives(aseg, aseg + s->sh_size);
if (IS_ENABLED(CONFIG_EXPOLINE) &&
- (str_has_prefix(secname, ".s390_indirect")))
+ (strprefix(secname, ".s390_indirect")))
nospec_revert(aseg, aseg + s->sh_size);
if (IS_ENABLED(CONFIG_EXPOLINE) &&
- (str_has_prefix(secname, ".s390_return")))
+ (strprefix(secname, ".s390_return")))
nospec_revert(aseg, aseg + s->sh_size);
if (IS_ENABLED(CONFIG_STACKPROTECTOR) &&
- (str_has_prefix(secname, "__stack_protector_loc"))) {
+ (strprefix(secname, "__stack_protector_loc"))) {
rc = stack_protector_apply(aseg, aseg + s->sh_size);
if (rc)
break;
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index b60284328fe3..7074cdd58aa3 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -269,7 +269,7 @@ static void __init conmode_default(void)
#endif
return;
}
- if (str_has_prefix(ptr + 8, "3270")) {
+ if (strprefix(ptr + 8, "3270")) {
#if defined(CONFIG_TN3270_CONSOLE)
SET_CONSOLE_3270;
#elif defined(CONFIG_TN3215_CONSOLE)
@@ -277,7 +277,7 @@ static void __init conmode_default(void)
#elif defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE)
SET_CONSOLE_SCLP;
#endif
- } else if (str_has_prefix(ptr + 8, "3215")) {
+ } else if (strprefix(ptr + 8, "3215")) {
#if defined(CONFIG_TN3215_CONSOLE)
SET_CONSOLE_3215;
#elif defined(CONFIG_TN3270_CONSOLE)
diff --git a/arch/s390/lib/test_unwind.c b/arch/s390/lib/test_unwind.c
index bb47958f5aed..8d6b6efe02fc 100644
--- a/arch/s390/lib/test_unwind.c
+++ b/arch/s390/lib/test_unwind.c
@@ -87,10 +87,10 @@ static noinline int test_unwind(struct task_struct *task, struct pt_regs *regs,
kunit_err(current_test, "backtrace buffer is too small\n");
}
frame_count += 1;
- if (prev_is_func2 && str_has_prefix(sym, "unwindme_func1"))
+ if (prev_is_func2 && strprefix(sym, "unwindme_func1"))
seen_func2_func1 = true;
- prev_is_func2 = str_has_prefix(sym, "unwindme_func2");
- if (str_has_prefix(sym, "arch_rethook_trampoline+0x0/"))
+ prev_is_func2 = strprefix(sym, "unwindme_func2");
+ if (strprefix(sym, "arch_rethook_trampoline+0x0/"))
seen_arch_rethook_trampoline = true;
}
diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c
index b0b65416d74d..efa92e925461 100644
--- a/drivers/gpio/gpio-aggregator.c
+++ b/drivers/gpio/gpio-aggregator.c
@@ -1546,7 +1546,7 @@ static ssize_t gpio_aggregator_delete_device_store(struct device_driver *driver,
unsigned int id;
int error;
- if (!str_has_prefix(buf, DRV_NAME "."))
+ if (!strprefix(buf, DRV_NAME "."))
return -EINVAL;
error = kstrtouint(buf + strlen(DRV_NAME "."), 10, &id);
diff --git a/drivers/gpu/drm/xe/xe_configfs.c b/drivers/gpu/drm/xe/xe_configfs.c
index 2ddd707a6dbd..8bd11f5bdfa1 100644
--- a/drivers/gpu/drm/xe/xe_configfs.c
+++ b/drivers/gpu/drm/xe/xe_configfs.c
@@ -521,7 +521,7 @@ static const struct engine_info *lookup_engine_info(const char *pattern, u64 *ma
u8 instance;
u16 bit;
- if (!str_has_prefix(pattern, engine_info[i].cls))
+ if (!strprefix(pattern, engine_info[i].cls))
continue;
pattern += strlen(engine_info[i].cls);
@@ -836,7 +836,7 @@ static ssize_t parse_wa_bb_lines(const char *lines,
p += ret;
p += strspn(p, " \t");
- if (str_has_prefix(p, "cmd")) {
+ if (strprefix(p, "cmd")) {
for (p += strlen("cmd"); *p;) {
ret = parse_hex(p, &val);
if (ret < 0)
@@ -848,7 +848,7 @@ static ssize_t parse_wa_bb_lines(const char *lines,
dwords++;
wa_bb_append(&wa_bb[info->engine_class], val);
}
- } else if (str_has_prefix(p, "reg")) {
+ } else if (strprefix(p, "reg")) {
p += strlen("reg");
ret = parse_hex(p, &val);
if (ret <= 0)
diff --git a/drivers/iio/pressure/hsc030pa.c b/drivers/iio/pressure/hsc030pa.c
index 0374d406b401..eaf5ee190be5 100644
--- a/drivers/iio/pressure/hsc030pa.c
+++ b/drivers/iio/pressure/hsc030pa.c
@@ -476,7 +476,7 @@ int hsc_common_probe(struct device *dev, hsc_recv_fn recv)
return dev_err_probe(dev, ret,
"honeywell,pressure-triplet could not be read\n");
- if (str_has_prefix(triplet, "NA")) {
+ if (strprefix(triplet, "NA")) {
ret = device_property_read_u32(dev, "honeywell,pmin-pascal",
&hsc->pmin);
if (ret)
diff --git a/drivers/md/dm-inlinecrypt.c b/drivers/md/dm-inlinecrypt.c
index 3479dfe5f708..4a1cc2da4c29 100644
--- a/drivers/md/dm-inlinecrypt.c
+++ b/drivers/md/dm-inlinecrypt.c
@@ -257,7 +257,7 @@ static int inlinecrypt_ctr_optional(struct dm_target *ti,
ti->error = "Not enough feature arguments";
return -EINVAL;
}
- if (str_has_prefix(opt_string, "keytype:")) {
+ if (strprefix(opt_string, "keytype:")) {
const char *val = opt_string + strlen("keytype:");
if (!*val) {
diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c
index 7d7ba6d349fc..725245a1680b 100644
--- a/drivers/media/i2c/ds90ub960.c
+++ b/drivers/media/i2c/ds90ub960.c
@@ -4692,7 +4692,7 @@ ub960_fwnode_get_link_by_regs(struct fwnode_handle *links_fwnode,
fwnode_for_each_child_node(links_fwnode, link_fwnode) {
u32 link_num;
- if (!str_has_prefix(fwnode_get_name(link_fwnode), "link@"))
+ if (!strprefix(fwnode_get_name(link_fwnode), "link@"))
continue;
ret = fwnode_property_read_u32(link_fwnode, "reg", &link_num);
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 9751acc2bf83..2dd18b34a378 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -1147,7 +1147,7 @@ static const char *scp_get_default_fw_path(struct device *dev, int core_id)
return ERR_PTR(-EINVAL);
/* If the compatible string starts with "mediatek,mt" assume that it's ok */
- if (!str_has_prefix(compatible, "mediatek,mt"))
+ if (!strprefix(compatible, "mediatek,mt"))
return ERR_PTR(-EINVAL);
if (core_id >= 0)
diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c b/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c
index cca91c6d71a5..2cfe5f92ca3b 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c
@@ -222,7 +222,7 @@ static int atomisp_csi2_get_pmc_clk_nr_from_acpi_pr0(struct acpi_device *adev)
acpi_get_name(rhandle, ACPI_SINGLE_NAME, &b_name);
- if (str_has_prefix(name, "CLK") && !kstrtou8(&name[3], 10, &clock_num) &&
+ if (strprefix(name, "CLK") && !kstrtou8(&name[3], 10, &clock_num) &&
clock_num <= 4) {
ret = clock_num;
break;
diff --git a/drivers/tty/serial/serial_base_bus.c b/drivers/tty/serial/serial_base_bus.c
index 5f23284a8778..1a5512457b74 100644
--- a/drivers/tty/serial/serial_base_bus.c
+++ b/drivers/tty/serial/serial_base_bus.c
@@ -33,11 +33,11 @@ static const struct device_type serial_port_type = {
static int serial_base_match(struct device *dev, const struct device_driver *drv)
{
if (dev->type == &serial_ctrl_type &&
- str_has_prefix(drv->name, serial_ctrl_type.name))
+ strprefix(drv->name, serial_ctrl_type.name))
return 1;
if (dev->type == &serial_port_type &&
- str_has_prefix(drv->name, serial_port_type.name))
+ strprefix(drv->name, serial_port_type.name))
return 1;
return 0;
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 40c332d2179d..d3c8afaae4b3 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -803,7 +803,7 @@ static void parse_grep(const char *str)
cp++;
while (isspace(*cp))
cp++;
- if (!str_has_prefix(cp, "grep ")) {
+ if (!strprefix(cp, "grep ")) {
kdb_printf("invalid 'pipe', see grephelp\n");
return;
}
diff --git a/kernel/kcsan/debugfs.c b/kernel/kcsan/debugfs.c
index 2af39ba5b70b..b945f9ab39a3 100644
--- a/kernel/kcsan/debugfs.c
+++ b/kernel/kcsan/debugfs.c
@@ -233,7 +233,7 @@ debugfs_write(struct file *file, const char __user *buf, size_t count, loff_t *o
WRITE_ONCE(kcsan_enabled, true);
} else if (!strcmp(arg, "off")) {
WRITE_ONCE(kcsan_enabled, false);
- } else if (str_has_prefix(arg, "microbench=")) {
+ } else if (strprefix(arg, "microbench=")) {
unsigned long iters;
if (kstrtoul(&arg[strlen("microbench=")], 0, &iters))
diff --git a/kernel/kcsan/report.c b/kernel/kcsan/report.c
index 11a48b78f8d1..00f9b12f6a6d 100644
--- a/kernel/kcsan/report.c
+++ b/kernel/kcsan/report.c
@@ -292,7 +292,7 @@ static int get_stack_skipnr(const unsigned long stack_entries[], int num_entries
cur = strnstr(buf, "kcsan_", len);
if (cur) {
cur += strlen("kcsan_");
- if (!str_has_prefix(cur, "test"))
+ if (!strprefix(cur, "test"))
continue; /* KCSAN runtime function. */
/* KCSAN related test. */
}
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 2441b9e39343..e8ce9ad73389 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1860,8 +1860,8 @@ static bool is_cfi_preamble_symbol(unsigned long addr)
if (lookup_symbol_name(addr, symbuf))
return false;
- return str_has_prefix(symbuf, "__cfi_") ||
- str_has_prefix(symbuf, "__pfx_");
+ return strprefix(symbuf, "__cfi_") ||
+ strprefix(symbuf, "__pfx_");
}
static int check_kprobe_address_safe(struct kprobe *p,
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
index e618bcf75e2d..5408c4de5b01 100644
--- a/kernel/locking/locktorture.c
+++ b/kernel/locking/locktorture.c
@@ -1277,16 +1277,16 @@ static int __init lock_torture_init(void)
}
#ifdef CONFIG_DEBUG_MUTEXES
- if (str_has_prefix(torture_type, "mutex"))
+ if (strprefix(torture_type, "mutex"))
cxt.debug_lock = true;
#endif
#ifdef CONFIG_DEBUG_RT_MUTEXES
- if (str_has_prefix(torture_type, "rtmutex"))
+ if (strprefix(torture_type, "rtmutex"))
cxt.debug_lock = true;
#endif
#ifdef CONFIG_DEBUG_SPINLOCK
- if ((str_has_prefix(torture_type, "spin")) ||
- (str_has_prefix(torture_type, "rw_lock")))
+ if ((strprefix(torture_type, "spin")) ||
+ (strprefix(torture_type, "rw_lock")))
cxt.debug_lock = true;
#endif
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 5429e9f19b65..763f84900e4b 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -781,7 +781,7 @@ static suspend_state_t decode_state(const char *buf, size_t n)
len = p ? p - buf : n;
/* Check hibernation first. */
- if (len == 4 && str_has_prefix(buf, "disk"))
+ if (len == 4 && strprefix(buf, "disk"))
return PM_SUSPEND_MAX;
#ifdef CONFIG_SUSPEND
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 49d135bc2fbf..d467cdf9c805 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -2182,7 +2182,7 @@ static int f_show(struct seq_file *m, void *v)
*/
array_descriptor = strchr(field->type, '[');
- if (str_has_prefix(field->type, "__data_loc"))
+ if (strprefix(field->type, "__data_loc"))
array_descriptor = NULL;
if (!array_descriptor)
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 1aae7d7c6dc5..c099bfbb9fb6 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -1468,9 +1468,9 @@ static int parse_action(char *str, struct hist_trigger_attrs *attrs)
if (attrs->n_actions >= HIST_ACTIONS_MAX)
return ret;
- if ((str_has_prefix(str, "onmatch(")) ||
- (str_has_prefix(str, "onmax(")) ||
- (str_has_prefix(str, "onchange("))) {
+ if ((strprefix(str, "onmatch(")) ||
+ (strprefix(str, "onmax(")) ||
+ (strprefix(str, "onchange("))) {
attrs->action_str[attrs->n_actions] = kstrdup(str, GFP_KERNEL);
if (!attrs->action_str[attrs->n_actions]) {
ret = -ENOMEM;
@@ -1508,7 +1508,7 @@ static int parse_assignment(struct trace_array *tr,
ret = -ENOMEM;
goto out;
}
- } else if (str_has_prefix(str, "name=")) {
+ } else if (strprefix(str, "name=")) {
attrs->name = kstrdup(str, GFP_KERNEL);
if (!attrs->name) {
ret = -ENOMEM;
@@ -3775,7 +3775,7 @@ static int action_parse(struct trace_array *tr, char *str, struct action_data *d
goto out;
}
- if (str_has_prefix(action_name, "save")) {
+ if (strprefix(action_name, "save")) {
char *params = strsep(&str, ")");
if (!params) {
@@ -3801,7 +3801,7 @@ static int action_parse(struct trace_array *tr, char *str, struct action_data *d
data->track_data.save_data = save_track_data_vars;
data->fn = ontrack_action;
data->action = ACTION_SAVE;
- } else if (str_has_prefix(action_name, "snapshot")) {
+ } else if (strprefix(action_name, "snapshot")) {
char *params = strsep(&str, ")");
if (!str) {
@@ -3826,7 +3826,7 @@ static int action_parse(struct trace_array *tr, char *str, struct action_data *d
} else {
char *params = strsep(&str, ")");
- if (str_has_prefix(action_name, "trace"))
+ if (strprefix(action_name, "trace"))
data->use_trace_keyword = true;
if (params) {
diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
index e2870212e58d..016ca522e5af 100644
--- a/kernel/trace/trace_events_synth.c
+++ b/kernel/trace/trace_events_synth.c
@@ -167,7 +167,7 @@ static int synth_event_define_fields(struct trace_event_call *call)
static bool synth_field_signed(char *type)
{
- if (str_has_prefix(type, "u"))
+ if (strprefix(type, "u"))
return false;
if (strcmp(type, "gfp_t") == 0)
return false;
diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c
index f658c3a77aa7..8669f11fb9bd 100644
--- a/kernel/trace/trace_events_user.c
+++ b/kernel/trace/trace_events_user.c
@@ -1098,13 +1098,13 @@ static int user_field_size(const char *type)
return sizeof(char);
if (strcmp(type, "unsigned char") == 0)
return sizeof(unsigned char);
- if (str_has_prefix(type, "char["))
+ if (strprefix(type, "char["))
return user_field_array_size(type);
- if (str_has_prefix(type, "unsigned char["))
+ if (strprefix(type, "unsigned char["))
return user_field_array_size(type);
- if (str_has_prefix(type, "__data_loc "))
+ if (strprefix(type, "__data_loc "))
return sizeof(u32);
- if (str_has_prefix(type, "__rel_loc "))
+ if (strprefix(type, "__rel_loc "))
return sizeof(u32);
/* Unknown basic type, error */
@@ -1145,10 +1145,10 @@ static int user_event_add_field(struct user_event *user, const char *type,
if (!field)
return -ENOMEM;
- if (str_has_prefix(type, "__data_loc "))
+ if (strprefix(type, "__data_loc "))
goto add_validator;
- if (str_has_prefix(type, "__rel_loc ")) {
+ if (strprefix(type, "__rel_loc ")) {
validator_flags |= VALIDATOR_REL;
goto add_validator;
}
@@ -1349,12 +1349,12 @@ static const char *user_field_format(const char *type)
static bool user_field_is_dyn_string(const char *type, const char **str_func)
{
- if (str_has_prefix(type, "__data_loc ")) {
+ if (strprefix(type, "__data_loc ")) {
*str_func = "__get_str";
goto check;
}
- if (str_has_prefix(type, "__rel_loc ")) {
+ if (strprefix(type, "__rel_loc ")) {
*str_func = "__get_rel_str";
goto check;
}
@@ -1401,7 +1401,7 @@ static int user_field_set_string(struct ftrace_event_field *field,
pos += snprintf(buf + pos, LEN_OR_ZERO, " ");
pos += snprintf(buf + pos, LEN_OR_ZERO, "%s", field->name);
- if (str_has_prefix(field->type, "struct "))
+ if (strprefix(field->type, "struct "))
pos += snprintf(buf + pos, LEN_OR_ZERO, " %d", field->size);
if (colon)
@@ -1808,7 +1808,7 @@ static int user_event_create(const char *raw_command)
char *name;
int ret;
- if (!str_has_prefix(raw_command, USER_EVENTS_PREFIX))
+ if (!strprefix(raw_command, USER_EVENTS_PREFIX))
return -ECANCELED;
raw_command += USER_EVENTS_PREFIX_LEN;
@@ -1861,7 +1861,7 @@ static int user_event_show(struct seq_file *m, struct dyn_event *ev)
seq_printf(m, "%s %s", field->type, field->name);
- if (str_has_prefix(field->type, "struct "))
+ if (strprefix(field->type, "struct "))
seq_printf(m, " %d", field->size);
depth++;
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index a880a90642d7..62acdf737c12 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -370,10 +370,10 @@ static int parse_this_cpu(char *arg, struct traceprobe_parse_context *ctx)
trace_probe_log_err(ctx->offset, NOSUP_PERCPU);
return -EINVAL;
}
- if (str_has_prefix(arg, THIS_CPU_PTR_PREFIX)) {
+ if (strprefix(arg, THIS_CPU_PTR_PREFIX)) {
arg += THIS_CPU_PTR_LEN;
ctx->offset += THIS_CPU_PTR_LEN;
- } else if (str_has_prefix(arg, THIS_CPU_READ_PREFIX)) {
+ } else if (strprefix(arg, THIS_CPU_READ_PREFIX)) {
arg += THIS_CPU_READ_LEN;
ctx->offset += THIS_CPU_READ_LEN;
is_read = true;
@@ -745,7 +745,7 @@ static int parse_btf_arg(char *varname,
u32 tid;
/* Note: field is not separated at this point, so check prefix. */
- if (!str_has_prefix(varname, "$current") &&
+ if (!strprefix(varname, "$current") &&
!ctx->funcname && !(ctx->flags & TPARG_FL_TEVENT))
return -EINVAL;
@@ -1001,8 +1001,8 @@ static int handle_typecast(char *arg, struct traceprobe_parse_context *ctx)
ctx->offset += 1;
tmp++;
} else if (*tmp == '+' || *tmp == '-' ||
- str_has_prefix(tmp, THIS_CPU_PTR_PREFIX) ||
- str_has_prefix(tmp, THIS_CPU_READ_PREFIX)) {
+ strprefix(tmp, THIS_CPU_PTR_PREFIX) ||
+ strprefix(tmp, THIS_CPU_READ_PREFIX)) {
/* Dereference can have another field access inside it. */
char *open = strchr(tmp + 1, '(');
@@ -1412,7 +1412,7 @@ static int parse_probe_vars(char *orig_arg, const struct fetch_type *t,
if (ctx->flags & TPARG_FL_TEVENT)
goto inval;
- if (str_has_prefix(arg, "retval"))
+ if (strprefix(arg, "retval"))
return parse_probe_var_retval(orig_arg, pcode, end, ctx);
len = str_has_prefix(arg, "stack");
@@ -1420,7 +1420,7 @@ static int parse_probe_vars(char *orig_arg, const struct fetch_type *t,
return parse_probe_var_stack(arg, len, code, ctx);
/* $current returns the address of the current task_struct. */
- if (str_has_prefix(arg, "current"))
+ if (strprefix(arg, "current"))
return parse_probe_var_current(orig_arg, arg, pcode, end, ctx);
len = str_has_prefix(arg, "arg");
@@ -1642,8 +1642,8 @@ static int parse_probe_arg_nested(char **parg, struct traceprobe_parse_context *
while (true) {
/* Determine if this is a nested argument */
if (arg[0] != '+' && arg[0] != '-' && arg[0] != '(' &&
- !str_has_prefix(arg, THIS_CPU_PTR_PREFIX) &&
- !str_has_prefix(arg, THIS_CPU_READ_PREFIX))
+ !strprefix(arg, THIS_CPU_PTR_PREFIX) &&
+ !strprefix(arg, THIS_CPU_READ_PREFIX))
break;
/* If nested, check the maximum depth limit */
@@ -2228,7 +2228,7 @@ static int argv_has_var_arg(int argc, const char *argv[], int *args_idx,
int i, found = 0;
for (i = 0; i < argc; i++)
- if (str_has_prefix(argv[i], "$arg")) {
+ if (strprefix(argv[i], "$arg")) {
trace_probe_log_set_index(i + 2);
if (!tparg_is_function_entry(ctx->flags) &&
@@ -2335,7 +2335,7 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[],
continue;
}
- if (str_has_prefix(argv[i], "$arg")) {
+ if (strprefix(argv[i], "$arg")) {
char *type = NULL;
n = simple_strtoul(argv[i] + 4, &type, 10);
diff --git a/mm/arch_numa.c b/mm/arch_numa.c
index a4b1732274fa..8380b8fe11d5 100644
--- a/mm/arch_numa.c
+++ b/mm/arch_numa.c
@@ -24,7 +24,7 @@ static __init int numa_parse_early_param(char *opt)
{
if (!opt)
return -EINVAL;
- if (str_has_prefix(opt, "off"))
+ if (strprefix(opt, "off"))
numa_off = true;
if (!strncmp(opt, "fake=", 5))
return numa_emu_cmdline(opt + 5);
diff --git a/mm/kfence/report.c b/mm/kfence/report.c
index d548536864b1..e6fae0c2b9b5 100644
--- a/mm/kfence/report.c
+++ b/mm/kfence/report.c
@@ -97,9 +97,9 @@ static int get_stack_skipnr(const unsigned long stack_entries[], int num_entries
for (skipnr = 0; skipnr < num_entries; skipnr++) {
int len = scnprintf(buf, sizeof(buf), "%ps", (void *)stack_entries[skipnr]);
- if (str_has_prefix(buf, ARCH_FUNC_PREFIX "kfence_") ||
- str_has_prefix(buf, ARCH_FUNC_PREFIX "__kfence_") ||
- str_has_prefix(buf, ARCH_FUNC_PREFIX "__kmem_cache_free") ||
+ if (strprefix(buf, ARCH_FUNC_PREFIX "kfence_") ||
+ strprefix(buf, ARCH_FUNC_PREFIX "__kfence_") ||
+ strprefix(buf, ARCH_FUNC_PREFIX "__kmem_cache_free") ||
!strncmp(buf, ARCH_FUNC_PREFIX "__slab_free", len)) {
/*
* In case of tail calls from any of the below to any of
@@ -114,10 +114,10 @@ static int get_stack_skipnr(const unsigned long stack_entries[], int num_entries
* into the slab allocators. Includes the *_bulk() variants by
* checking prefixes.
*/
- if (str_has_prefix(buf, ARCH_FUNC_PREFIX "kfree") ||
- str_has_prefix(buf, ARCH_FUNC_PREFIX "kmem_cache_free") ||
- str_has_prefix(buf, ARCH_FUNC_PREFIX "__kmalloc") ||
- str_has_prefix(buf, ARCH_FUNC_PREFIX "kmem_cache_alloc"))
+ if (strprefix(buf, ARCH_FUNC_PREFIX "kfree") ||
+ strprefix(buf, ARCH_FUNC_PREFIX "kmem_cache_free") ||
+ strprefix(buf, ARCH_FUNC_PREFIX "__kmalloc") ||
+ strprefix(buf, ARCH_FUNC_PREFIX "kmem_cache_alloc"))
goto found;
}
if (fallback < num_entries)
diff --git a/sound/soc/sdw_utils/soc_sdw_senary_sdca.c b/sound/soc/sdw_utils/soc_sdw_senary_sdca.c
index 5c2cd75307c9..afaca66e41ef 100644
--- a/sound/soc/sdw_utils/soc_sdw_senary_sdca.c
+++ b/sound/soc/sdw_utils/soc_sdw_senary_sdca.c
@@ -33,7 +33,7 @@ static const struct codec_route_map codec_routes[] = {
static const struct codec_route_map *get_codec_route_map(const char *dai_name)
{
for (size_t i = 0; i < ARRAY_SIZE(codec_routes); i++) {
- if (str_has_prefix(dai_name, codec_routes[i].codec_name))
+ if (strprefix(dai_name, codec_routes[i].codec_name))
return &codec_routes[i];
}
return NULL;
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v6 15/19] treewide: Replace some uses of str_has_prefix() by strprefix()
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (13 preceding siblings ...)
2026-11-14 15:23 ` [PATCH v6 14/19] treewide: Replace boolean uses of str_has_prefix() by strprefix() Alejandro Colomar
@ 2026-11-14 15:23 ` Alejandro Colomar
2026-11-14 15:34 ` sashiko-bot
2026-11-14 15:23 ` [PATCH v6 16/19] string: Add strsuffix() Alejandro Colomar
` (3 subsequent siblings)
18 siblings, 1 reply; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:23 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio
[-- Attachment #1: Type: text/plain, Size: 8026 bytes --]
In many cases, it results in simpler code. For example:
- prefix_len = str_has_prefix(name, PDSC_FW_COMPONENT_PREFIX);
- if (prefix_len)
- name += prefix_len;
+ name = strprefix(name, PDSC_FW_COMPONENT_PREFIX) ?: name;
It avoids explicit pointer arithmetic, which also prevents certain bugs.
After this commit, only a few uses of str_has_prefix() remain. Those
are difficult to remove, as the surrounding code is deeply based on
lengths. Let's leave those, as it's too risky to touch that code.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
drivers/net/ethernet/amd/pds_core/fw.c | 5 +--
kernel/printk/braille.c | 14 ++++----
kernel/trace/trace.c | 9 +++---
kernel/trace/trace_events.c | 3 +-
kernel/trace/trace_events_hist.c | 44 ++++++++++++--------------
kernel/trace/trace_events_synth.c | 8 +++--
kernel/trace/trace_stack.c | 6 ++--
7 files changed, 42 insertions(+), 47 deletions(-)
diff --git a/drivers/net/ethernet/amd/pds_core/fw.c b/drivers/net/ethernet/amd/pds_core/fw.c
index 7fe4594e9f9b..3f0b1137dd90 100644
--- a/drivers/net/ethernet/amd/pds_core/fw.c
+++ b/drivers/net/ethernet/amd/pds_core/fw.c
@@ -50,16 +50,13 @@ void pdsc_fw_components_invalidate(struct pdsc *pdsc)
static u8 pdsc_name_to_fw_type(const char *name)
{
- size_t prefix_len;
int i;
/* "fw" without suffix maps to main firmware */
if (!strcmp(name, "fw"))
return PDS_CORE_FW_TYPE_MAIN;
- prefix_len = str_has_prefix(name, PDSC_FW_COMPONENT_PREFIX);
- if (prefix_len)
- name += prefix_len;
+ name = strprefix(name, PDSC_FW_COMPONENT_PREFIX) ?: name;
for (i = 1; i < ARRAY_SIZE(pdsc_fw_type_names); i++) {
if (pdsc_fw_type_names[i] &&
diff --git a/kernel/printk/braille.c b/kernel/printk/braille.c
index 17a9591e54ff..18847d88140b 100644
--- a/kernel/printk/braille.c
+++ b/kernel/printk/braille.c
@@ -11,18 +11,18 @@
int _braille_console_setup(char **str, char **brl_options)
{
- size_t len;
+ char *p;
- len = str_has_prefix(*str, "brl,");
- if (len) {
+ p = strprefix(*str, "brl,");
+ if (p) {
*brl_options = "";
- *str += len;
+ *str = p;
return 0;
}
- len = str_has_prefix(*str, "brl=");
- if (len) {
- *brl_options = *str + len;
+ p = strprefix(*str, "brl=");
+ if (p) {
+ *brl_options = p;
*str = strchr(*brl_options, ',');
if (!*str) {
pr_err("need port name after brl=\n");
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index e8c4efa8107b..1c40a00c5bd7 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4085,19 +4085,18 @@ int set_tracer_flag(struct trace_array *tr, u64 mask, int enabled)
int trace_set_options(struct trace_array *tr, char *option)
{
- char *cmp;
+ char *cmp, *p;
int neg = 0;
int ret;
size_t orig_len = strlen(option);
- int len;
cmp = strstrip(option);
- len = str_has_prefix(cmp, "no");
- if (len)
+ p = strprefix(cmp, "no");
+ if (p)
neg = 1;
- cmp += len;
+ cmp = p;
mutex_lock(&event_mutex);
mutex_lock(&trace_types_lock);
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index d467cdf9c805..72e42def1dd0 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -266,9 +266,8 @@ static struct trace_event_fields *find_event_field(const char *fmt,
const char *p = fmt;
int len;
- if (!(len = str_has_prefix(fmt, "REC->")))
+ if (!(fmt = strprefix(fmt, "REC->")))
return NULL;
- fmt += len;
for (p = fmt; *p; p++) {
if (!isalnum(*p) && *p != '_')
break;
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index c099bfbb9fb6..d5578b67ce9f 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -1485,25 +1485,26 @@ static int parse_action(char *str, struct hist_trigger_attrs *attrs)
static int parse_assignment(struct trace_array *tr,
char *str, struct hist_trigger_attrs *attrs)
{
- int len, ret = 0;
+ char *p;
+ int ret = 0;
- if ((len = str_has_prefix(str, "key=")) ||
- (len = str_has_prefix(str, "keys="))) {
- attrs->keys_str = kstrdup(str + len, GFP_KERNEL);
+ if ((p = strprefix(str, "key=")) ||
+ (p = strprefix(str, "keys="))) {
+ attrs->keys_str = kstrdup(p, GFP_KERNEL);
if (!attrs->keys_str) {
ret = -ENOMEM;
goto out;
}
- } else if ((len = str_has_prefix(str, "val=")) ||
- (len = str_has_prefix(str, "vals=")) ||
- (len = str_has_prefix(str, "values="))) {
- attrs->vals_str = kstrdup(str + len, GFP_KERNEL);
+ } else if ((p = strprefix(str, "val=")) ||
+ (p = strprefix(str, "vals=")) ||
+ (p = strprefix(str, "values="))) {
+ attrs->vals_str = kstrdup(p, GFP_KERNEL);
if (!attrs->vals_str) {
ret = -ENOMEM;
goto out;
}
- } else if ((len = str_has_prefix(str, "sort="))) {
- attrs->sort_key_str = kstrdup(str + len, GFP_KERNEL);
+ } else if ((p = strprefix(str, "sort="))) {
+ attrs->sort_key_str = kstrdup(p, GFP_KERNEL);
if (!attrs->sort_key_str) {
ret = -ENOMEM;
goto out;
@@ -1514,17 +1515,15 @@ static int parse_assignment(struct trace_array *tr,
ret = -ENOMEM;
goto out;
}
- } else if ((len = str_has_prefix(str, "clock="))) {
- str += len;
-
- str = strstrip(str);
- attrs->clock = kstrdup(str, GFP_KERNEL);
+ } else if ((p = strprefix(str, "clock="))) {
+ p = strstrip(p);
+ attrs->clock = kstrdup(p, GFP_KERNEL);
if (!attrs->clock) {
ret = -ENOMEM;
goto out;
}
- } else if ((len = str_has_prefix(str, "size="))) {
- int map_bits = parse_map_size(str + len);
+ } else if ((p = strprefix(str, "size="))) {
+ int map_bits = parse_map_size(p);
if (map_bits < 0) {
ret = map_bits;
@@ -4881,8 +4880,7 @@ static int parse_actions(struct hist_trigger_data *hist_data)
struct action_data *data;
unsigned int i;
int ret = 0;
- char *str;
- int len;
+ char *str, *p;
for (i = 0; i < hist_data->attrs->n_actions; i++) {
enum handler_id hid = 0;
@@ -4890,14 +4888,14 @@ static int parse_actions(struct hist_trigger_data *hist_data)
str = hist_data->attrs->action_str[i];
- if ((len = str_has_prefix(str, "onmatch(")))
+ if ((p = strprefix(str, "onmatch(")))
hid = HANDLER_ONMATCH;
- else if ((len = str_has_prefix(str, "onmax(")))
+ else if ((p = strprefix(str, "onmax(")))
hid = HANDLER_ONMAX;
- else if ((len = str_has_prefix(str, "onchange(")))
+ else if ((p = strprefix(str, "onchange(")))
hid = HANDLER_ONCHANGE;
- action_str = str + len;
+ action_str = p ?: str;
switch (hid) {
case HANDLER_ONMATCH:
diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
index 016ca522e5af..2a7df262aa8f 100644
--- a/kernel/trace/trace_events_synth.c
+++ b/kernel/trace/trace_events_synth.c
@@ -2268,12 +2268,14 @@ static int create_synth_event(const char *raw_command)
/* This interface accepts group name prefix */
if (strchr(name, '/')) {
- len = str_has_prefix(name, SYNTH_SYSTEM "/");
- if (len == 0) {
+ const char *n;
+
+ n = strprefix(name, SYNTH_SYSTEM "/");
+ if (!n) {
synth_err(SYNTH_ERR_INVALID_DYN_CMD, 0);
return -EINVAL;
}
- name += len;
+ name = n;
}
len = name - raw_command;
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index e7f4e523587d..3f8ddb7b8530 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -539,10 +539,10 @@ static char stack_trace_filter_buf[COMMAND_LINE_SIZE+1] __initdata;
static __init int enable_stacktrace(char *str)
{
- int len;
+ char *p;
- if ((len = str_has_prefix(str, "_filter=")))
- strscpy(stack_trace_filter_buf, str + len);
+ if ((p = strprefix(str, "_filter=")))
+ strscpy(stack_trace_filter_buf, p);
stack_tracer_enabled = 1;
return 1;
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v6 15/19] treewide: Replace some uses of str_has_prefix() by strprefix()
2026-11-14 15:23 ` [PATCH v6 15/19] treewide: Replace some " Alejandro Colomar
@ 2026-11-14 15:34 ` sashiko-bot
0 siblings, 0 replies; 24+ messages in thread
From: sashiko-bot @ 2026-11-14 15:34 UTC (permalink / raw)
To: Alejandro Colomar; +Cc: devicetree, linux-gpio, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [High] tracing: NULL pointer dereference in trace_set_options()
--
commit c09c1b839b46a18b156e43281c4fb679a76cfe40
Author: Alejandro Colomar <alx@kernel.org>
treewide: Replace some uses of str_has_prefix() by strprefix()
This commit replaces several callers of str_has_prefix() across the tree
with strprefix() to avoid manual pointer arithmetic.
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index 4ccdefb5c3efe..f9f3faaede094 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -4085,19 +4085,18 @@ int set_tracer_flag(struct trace_array *tr, u64 mask, int enabled)
>
> int trace_set_options(struct trace_array *tr, char *option)
> {
> - char *cmp;
> + char *cmp, *p;
> int neg = 0;
> int ret;
> size_t orig_len = strlen(option);
> - int len;
>
> cmp = strstrip(option);
>
> - len = str_has_prefix(cmp, "no");
> - if (len)
> + p = strprefix(cmp, "no");
> + if (p)
> neg = 1;
>
> - cmp += len;
> + cmp = p;
[Severity: High]
Does this set cmp to NULL when the option does not start with "no"?
strprefix() returns NULL on a non-match, and "cmp = p;" runs outside the
"if (p)" check, causing a NULL pointer dereference when cmp is passed to
match_string() right below.
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1794667407.git.alx@kernel.org?part=15
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v6 16/19] string: Add strsuffix()
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (14 preceding siblings ...)
2026-11-14 15:23 ` [PATCH v6 15/19] treewide: Replace some " Alejandro Colomar
@ 2026-11-14 15:23 ` Alejandro Colomar
2026-11-14 15:24 ` [PATCH v6 17/19] string: Make strends() a legacy alias for strsuffix() Alejandro Colomar
` (2 subsequent siblings)
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:23 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio
[-- Attachment #1: Type: text/plain, Size: 1571 bytes --]
This is drop-in compatible with strends(), but is more useful, as it
gives more information.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
include/linux/string.h | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/include/linux/string.h b/include/linux/string.h
index 6b0de932e23a..2f7fb2c70662 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -47,8 +47,8 @@
/**
* streq - strings equal
*
- * @s1: string to compare
- * @s2: string to compare
+ * @s1: String to compare
+ * @s2: String to compare
*
* Compare two strings for equality.
*
@@ -610,6 +610,30 @@ static inline const char *strprefix(const char *s, const char *prefix)
}
#define strprefix(s, pfx) const_cast(CQChar_of(s) *, strprefix(s, pfx))
+/**
+ * strsuffix - string suffix
+ * @s: The string to be tested
+ * @suffix: The string to see if @s ends with
+ *
+ * Returns:
+ * * @s + strlen(@s) - strlen(@suffix) if @s ends with @suffix
+ * * NULL if @s does not end with @suffix
+ */
+__attribute__((nonnull(1, 2)))
+static inline const char *strsuffix(const char *s, const char *suffix)
+{
+ size_t len, sfxlen, off;
+
+ len = strlen(s);
+ sfxlen = strlen(suffix);
+ if (len < sfxlen)
+ return NULL;
+
+ off = len - sfxlen;
+ return streq(s + off, suffix) ? s + off : NULL;
+}
+#define strsuffix(s, sfx) const_cast(CQChar_of(s) *, strsuffix(s, sfx))
+
/**
* str_has_prefix - Test if a string has a given prefix
* @str: The string to test
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v6 17/19] string: Make strends() a legacy alias for strsuffix()
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (15 preceding siblings ...)
2026-11-14 15:23 ` [PATCH v6 16/19] string: Add strsuffix() Alejandro Colomar
@ 2026-11-14 15:24 ` Alejandro Colomar
2026-11-14 15:24 ` [PATCH v6 18/19] treewide: s/\<strends\>/strsuffix/g Alejandro Colomar
2026-11-14 15:24 ` [PATCH v6 19/19] string: Remove strends() Alejandro Colomar
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:24 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio
[-- Attachment #1: Type: text/plain, Size: 2022 bytes --]
strsuffix() is drop-in compatible with strends() --but see caveats
below--, and provides more functionality for cases where we're
interested in the position of where the suffix is in the string.
strsuffix() returns a pointer that can be converted to bool. This is
converted implicitly in most places, but if the target type is not bool,
then it might be problematic and require an explicit conversion with !!.
I checked that we don't need this anywhere, and also, I expect the
compiler would likely diagnose in such a case, so this should be safe.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
include/linux/string.h | 20 +-------------------
1 file changed, 1 insertion(+), 19 deletions(-)
diff --git a/include/linux/string.h b/include/linux/string.h
index 2f7fb2c70662..7469d4634b3e 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -633,6 +633,7 @@ static inline const char *strsuffix(const char *s, const char *suffix)
return streq(s + off, suffix) ? s + off : NULL;
}
#define strsuffix(s, sfx) const_cast(CQChar_of(s) *, strsuffix(s, sfx))
+#define strends(s, sfx) strsuffix(s, sfx) // legacy alias
/**
* str_has_prefix - Test if a string has a given prefix
@@ -656,23 +657,4 @@ static __always_inline size_t str_has_prefix(const char *str, const char *prefix
return strncmp(str, prefix, len) == 0 ? len : 0;
}
-/**
- * strends - Check if a string ends with another string.
- * @str: NULL-terminated string to check against @suffix
- * @suffix: NULL-terminated string defining the suffix to look for in @str
- *
- * Returns:
- * True if @str ends with @suffix. False in all other cases.
- */
-static inline bool __attribute__((nonnull(1, 2)))
-strends(const char *str, const char *suffix)
-{
- unsigned int str_len = strlen(str), suffix_len = strlen(suffix);
-
- if (str_len < suffix_len)
- return false;
-
- return !(strcmp(str + str_len - suffix_len, suffix));
-}
-
#endif /* _LINUX_STRING_H_ */
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v6 18/19] treewide: s/\<strends\>/strsuffix/g
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (16 preceding siblings ...)
2026-11-14 15:24 ` [PATCH v6 17/19] string: Make strends() a legacy alias for strsuffix() Alejandro Colomar
@ 2026-11-14 15:24 ` Alejandro Colomar
2026-11-14 15:24 ` [PATCH v6 19/19] string: Remove strends() Alejandro Colomar
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:24 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio
[-- Attachment #1: Type: text/plain, Size: 4137 bytes --]
Except for the changes to "lib/tests/string_kunit.c", this was
a scripted change:
$ git ls-files \
| grep '\.[ch]$' \
| grep -v -e ^tools/ -e ^scripts/ -e ^include/ \
| xargs grep -l strends \
| xargs sed -i 's/strends/strsuffix/g';
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
drivers/gpio/gpiolib-shared.c | 8 ++++----
drivers/of/property.c | 4 ++--
lib/tests/string_kunit.c | 20 ++++++++++----------
3 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/gpio/gpiolib-shared.c b/drivers/gpio/gpiolib-shared.c
index 8c9ac9d93304..677ec27e4e34 100644
--- a/drivers/gpio/gpiolib-shared.c
+++ b/drivers/gpio/gpiolib-shared.c
@@ -182,8 +182,8 @@ static int gpio_shared_of_traverse(struct device_node *curr)
* them. We can always just export the quirk list and
* iterate over it here.
*/
- if (!strends(prop->name, "-gpios") &&
- !strends(prop->name, "-gpio") &&
+ if (!strsuffix(prop->name, "-gpios") &&
+ !strsuffix(prop->name, "-gpio") &&
strcmp(prop->name, "gpios") != 0 &&
strcmp(prop->name, "gpio") != 0)
continue;
@@ -240,9 +240,9 @@ static int gpio_shared_of_traverse(struct device_node *curr)
list_add_tail(&entry->list, &gpio_shared_list);
}
- if (strends(prop->name, "gpios"))
+ if (strsuffix(prop->name, "gpios"))
suffix = "-gpios";
- else if (strends(prop->name, "gpio"))
+ else if (strsuffix(prop->name, "gpio"))
suffix = "-gpio";
else
suffix = NULL;
diff --git a/drivers/of/property.c b/drivers/of/property.c
index f0729619a2a0..3a272775a8b7 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -1344,7 +1344,7 @@ static struct device_node *parse_suffix_prop_cells(struct device_node *np,
{
struct of_phandle_args sup_args;
- if (!strends(prop_name, suffix))
+ if (!strsuffix(prop_name, suffix))
return NULL;
if (of_parse_phandle_with_args(np, prop_name, cells_name, index,
@@ -1433,7 +1433,7 @@ static struct device_node *parse_pinctrl_n(struct device_node *np,
static struct device_node *parse_gpios(struct device_node *np,
const char *prop_name, int index)
{
- if (strends(prop_name, ",nr-gpios"))
+ if (strsuffix(prop_name, ",nr-gpios"))
return NULL;
return parse_suffix_prop_cells(np, prop_name, index, "-gpios",
diff --git a/lib/tests/string_kunit.c b/lib/tests/string_kunit.c
index f603e89866d1..f07a9480cfb1 100644
--- a/lib/tests/string_kunit.c
+++ b/lib/tests/string_kunit.c
@@ -712,16 +712,16 @@ static void string_test_memtostr(struct kunit *test)
KUNIT_EXPECT_EQ(test, dest[7], '\0');
}
-static void string_test_strends(struct kunit *test)
+static void string_test_strsuffix(struct kunit *test)
{
- KUNIT_EXPECT_TRUE(test, strends("foo-bar", "bar"));
- KUNIT_EXPECT_TRUE(test, strends("foo-bar", "-bar"));
- KUNIT_EXPECT_TRUE(test, strends("foobar", "foobar"));
- KUNIT_EXPECT_TRUE(test, strends("foobar", ""));
- KUNIT_EXPECT_FALSE(test, strends("bar", "foobar"));
- KUNIT_EXPECT_FALSE(test, strends("", "foo"));
- KUNIT_EXPECT_FALSE(test, strends("foobar", "ba"));
- KUNIT_EXPECT_TRUE(test, strends("", ""));
+ KUNIT_EXPECT_TRUE(test, streq(strsuffix("foo-bar", "bar"), "bar"));
+ KUNIT_EXPECT_TRUE(test, streq(strsuffix("foo-bar", "-bar"), "-bar"));
+ KUNIT_EXPECT_TRUE(test, streq(strsuffix("foobar", "foobar"), "foobar"));
+ KUNIT_EXPECT_TRUE(test, streq(strsuffix("foobar", ""), ""));
+ KUNIT_EXPECT_NULL(test, strsuffix("bar", "foobar"));
+ KUNIT_EXPECT_NULL(test, strsuffix("", "foo"));
+ KUNIT_EXPECT_NULL(test, strsuffix("foobar", "ba"));
+ KUNIT_EXPECT_TRUE(test, streq(strsuffix("", ""), ""));
}
#if IS_ENABLED(CONFIG_STRING_KUNIT_BENCH)
@@ -914,7 +914,7 @@ static struct kunit_case string_test_cases[] = {
KUNIT_CASE(string_test_strlcat),
KUNIT_CASE(string_test_strtomem),
KUNIT_CASE(string_test_memtostr),
- KUNIT_CASE(string_test_strends),
+ KUNIT_CASE(string_test_strsuffix),
KUNIT_CASE(string_bench_strlen),
KUNIT_CASE(string_bench_strnlen),
KUNIT_CASE(string_bench_strchr),
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v6 19/19] string: Remove strends()
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
` (17 preceding siblings ...)
2026-11-14 15:24 ` [PATCH v6 18/19] treewide: s/\<strends\>/strsuffix/g Alejandro Colomar
@ 2026-11-14 15:24 ` Alejandro Colomar
18 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2026-11-14 15:24 UTC (permalink / raw)
To: linux-hardening
Cc: Alejandro Colomar, Krzysztof Kozlowski, Maciej W. Rozycki,
Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
linux-gpio
[-- Attachment #1: Type: text/plain, Size: 716 bytes --]
It's now unused, as it's been fully replaced by strsuffix().
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
include/linux/string.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/include/linux/string.h b/include/linux/string.h
index 7469d4634b3e..f41f30f8bac7 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -633,7 +633,6 @@ static inline const char *strsuffix(const char *s, const char *suffix)
return streq(s + off, suffix) ? s + off : NULL;
}
#define strsuffix(s, sfx) const_cast(CQChar_of(s) *, strsuffix(s, sfx))
-#define strends(s, sfx) strsuffix(s, sfx) // legacy alias
/**
* str_has_prefix - Test if a string has a given prefix
--
2.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 24+ messages in thread