Linux Hardening
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Add str_alloc_free()/str_free_alloc helper and
@ 2026-04-30  6:40 Jiazi Li
  2026-04-30  6:40 ` [PATCH v2 1/2] lib/string_choices: Add str_alloc_free() helper Jiazi Li
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Jiazi Li @ 2026-04-30  6:40 UTC (permalink / raw)
  To: Kees Cook, Andy Shevchenko, Julia Lawall, Nicolas Palix
  Cc: Jiazi Li, linux-hardening

Currently finds 4 locations:
./drivers/net/wireless/realtek/rtw89/fw.c:2557:7-12: opportunity for str_alloc_free(valid)
./drivers/net/wireless/realtek/rtw89/fw.c:2693:7-12: opportunity for str_alloc_free(valid)
./drivers/android/tests/binder_alloc_kunit.c:196:6-21: opportunity for str_alloc_free(alloc -> pages [ i ])
./mm/slub.c:1634:3-8: opportunity for str_alloc_free(alloc)

Jiazi Li (2):
  lib/string_choices: Add str_alloc_free() helper
  coccinelle: Add rules to find str_alloc_free() replacements

 include/linux/string_choices.h              |   6 +
 scripts/coccinelle/api/string_choices.cocci | 228 ++++++++++++--------
 2 files changed, 139 insertions(+), 95 deletions(-)

-- 
2.49.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/2] lib/string_choices: Add str_alloc_free() helper
  2026-04-30  6:40 [PATCH v2 0/2] Add str_alloc_free()/str_free_alloc helper and Jiazi Li
@ 2026-04-30  6:40 ` Jiazi Li
  2026-05-01  8:51   ` Andy Shevchenko
  2026-04-30  6:40 ` [PATCH v2 2/2] coccinelle: Add rules to find str_alloc_free() replacements Jiazi Li
  2026-05-01  8:54 ` [PATCH v2 0/2] Add str_alloc_free()/str_free_alloc helper and Andy Shevchenko
  2 siblings, 1 reply; 6+ messages in thread
From: Jiazi Li @ 2026-04-30  6:40 UTC (permalink / raw)
  To: Kees Cook, Andy Shevchenko, Julia Lawall, Nicolas Palix
  Cc: Jiazi Li, linux-hardening, mingzhu.wang

Add str_alloc_free() helper to return "alloc" or "free"
string literal depending on the boolean argument. Also add the
inversed variant str_free_alloc().

Suggested-by: Andy Shevchenko <andy@kernel.org>
Tested-by: mingzhu.wang <mingzhu.wang@transsion.com>
Signed-off-by: Jiazi Li <jqqlijiazi@gmail.com>
---
V2: Sorted function alphabetically.
---
 include/linux/string_choices.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/include/linux/string_choices.h b/include/linux/string_choices.h
index ee84087d4b26..65f346db95ba 100644
--- a/include/linux/string_choices.h
+++ b/include/linux/string_choices.h
@@ -17,6 +17,12 @@
 
 #include <linux/types.h>
 
+static inline const char *str_alloc_free(bool v)
+{
+	return v ? "alloc" : "free";
+}
+#define str_free_alloc(v)		str_alloc_free(!(v))
+
 static inline const char *str_assert_deassert(bool v)
 {
 	return v ? "assert" : "deassert";
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/2] coccinelle: Add rules to find str_alloc_free() replacements
  2026-04-30  6:40 [PATCH v2 0/2] Add str_alloc_free()/str_free_alloc helper and Jiazi Li
  2026-04-30  6:40 ` [PATCH v2 1/2] lib/string_choices: Add str_alloc_free() helper Jiazi Li
@ 2026-04-30  6:40 ` Jiazi Li
  2026-05-01  8:53   ` Andy Shevchenko
  2026-05-01  8:54 ` [PATCH v2 0/2] Add str_alloc_free()/str_free_alloc helper and Andy Shevchenko
  2 siblings, 1 reply; 6+ messages in thread
From: Jiazi Li @ 2026-04-30  6:40 UTC (permalink / raw)
  To: Kees Cook, Andy Shevchenko, Julia Lawall, Nicolas Palix
  Cc: Jiazi Li, linux-hardening, mingzhu.wang

Add rules for finding places where str_alloc_free()/str_free_alloc
can be used.
This currently finds 4 locations.

Adjust the position of some coccinelle rules, so they sorted in the
same order as they appear in the header.

Suggested-by: Andy Shevchenko <andy@kernel.org>
Tested-by: mingzhu.wang <mingzhu.wang@transsion.com>
Signed-off-by: Jiazi Li <jqqlijiazi@gmail.com>
---
V2: Keep coccinelle stances sorted in the same order as they appear in
the header.
---
 scripts/coccinelle/api/string_choices.cocci | 228 ++++++++++++--------
 1 file changed, 133 insertions(+), 95 deletions(-)

diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci
index 375045086912..516b30828380 100644
--- a/scripts/coccinelle/api/string_choices.cocci
+++ b/scripts/coccinelle/api/string_choices.cocci
@@ -7,109 +7,81 @@ virtual patch
 virtual context
 virtual report
 
-@str_plural depends on patch@
+@str_alloc_free depends on patch disable neg_if_exp@
 expression E;
 @@
-(
--	((E == 1) ? "" : "s")
-+	str_plural(E)
-|
--	((E > 1) ? "s" : "")
-+	str_plural(E)
-)
+-      ((E) ? "alloc" : "free")
++      str_alloc_free(E)
 
-@str_plural_r depends on !patch@
+@str_alloc_free_r depends on !patch disable neg_if_exp@
 expression E;
 position P;
 @@
-(
-*	(E@P == 1) ? "" : "s"
-|
-*	(E@P > 1) ? "s" : ""
-)
+*      E@P ? "alloc" : "free"
 
 @script:python depends on report@
-p << str_plural_r.P;
-e << str_plural_r.E;
+p << str_alloc_free_r.P;
+e << str_alloc_free_r.E;
 @@
 
-coccilib.report.print_report(p[0], "opportunity for str_plural(%s)" % e)
+coccilib.report.print_report(p[0], "opportunity for str_alloc_free(%s)" % e)
 
-@str_up_down depends on patch disable neg_if_exp@
+@str_free_alloc depends on patch disable neg_if_exp@
 expression E;
 @@
--	((E) ? "up" : "down")
-+	str_up_down(E)
+-      ((E) ? "free" : "alloc")
++      str_free_alloc(E)
 
-@str_up_down_r depends on !patch disable neg_if_exp@
+@str_free_alloc_r depends on !patch disable neg_if_exp@
 expression E;
 position P;
 @@
-*	E@P ? "up" : "down"
+*      E@P ? "free" : "alloc"
 
 @script:python depends on report@
-p << str_up_down_r.P;
-e << str_up_down_r.E;
+p << str_free_alloc_r.P;
+e << str_free_alloc_r.E;
 @@
 
-coccilib.report.print_report(p[0], "opportunity for str_up_down(%s)" % e)
+coccilib.report.print_report(p[0], "opportunity for str_free_alloc(%s)" % e)
 
-@str_down_up depends on patch disable neg_if_exp@
-expression E;
-@@
--      ((E) ? "down" : "up")
-+      str_down_up(E)
-
-@str_down_up_r depends on !patch disable neg_if_exp@
-expression E;
-position P;
-@@
-*      E@P ? "down" : "up"
-
-@script:python depends on report@
-p << str_down_up_r.P;
-e << str_down_up_r.E;
-@@
-
-coccilib.report.print_report(p[0], "opportunity for str_down_up(%s)" % e)
-
-@str_true_false depends on patch disable neg_if_exp@
+@str_enable_disable depends on patch@
 expression E;
 @@
--      ((E) ? "true" : "false")
-+      str_true_false(E)
+-      ((E) ? "enable" : "disable")
++      str_enable_disable(E)
 
-@str_true_false_r depends on !patch disable neg_if_exp@
+@str_enable_disable_r depends on !patch@
 expression E;
 position P;
 @@
-*      E@P ? "true" : "false"
+*      E@P ? "enable" : "disable"
 
 @script:python depends on report@
-p << str_true_false_r.P;
-e << str_true_false_r.E;
+p << str_enable_disable_r.P;
+e << str_enable_disable_r.E;
 @@
 
-coccilib.report.print_report(p[0], "opportunity for str_true_false(%s)" % e)
+coccilib.report.print_report(p[0], "opportunity for str_enable_disable(%s)" % e)
 
-@str_false_true depends on patch disable neg_if_exp@
+@str_enabled_disabled depends on patch@
 expression E;
 @@
--      ((E) ? "false" : "true")
-+      str_false_true(E)
+-      ((E) ? "enabled" : "disabled")
++      str_enabled_disabled(E)
 
-@str_false_true_r depends on !patch disable neg_if_exp@
+@str_enabled_disabled_r depends on !patch@
 expression E;
 position P;
 @@
-*      E@P ? "false" : "true"
+*      E@P ? "enabled" : "disabled"
 
 @script:python depends on report@
-p << str_false_true_r.P;
-e << str_false_true_r.E;
+p << str_enabled_disabled_r.P;
+e << str_enabled_disabled_r.E;
 @@
 
-coccilib.report.print_report(p[0], "opportunity for str_false_true(%s)" % e)
+coccilib.report.print_report(p[0], "opportunity for str_enabled_disabled(%s)" % e)
 
 @str_hi_lo depends on patch disable neg_if_exp@
 expression E;
@@ -187,43 +159,24 @@ e << str_low_high_r.E;
 
 coccilib.report.print_report(p[0], "opportunity for str_low_high(%s)" % e)
 
-@str_enable_disable depends on patch@
-expression E;
-@@
--      ((E) ? "enable" : "disable")
-+      str_enable_disable(E)
-
-@str_enable_disable_r depends on !patch@
-expression E;
-position P;
-@@
-*      E@P ? "enable" : "disable"
-
-@script:python depends on report@
-p << str_enable_disable_r.P;
-e << str_enable_disable_r.E;
-@@
-
-coccilib.report.print_report(p[0], "opportunity for str_enable_disable(%s)" % e)
-
-@str_enabled_disabled depends on patch@
+@str_on_off depends on patch@
 expression E;
 @@
--      ((E) ? "enabled" : "disabled")
-+      str_enabled_disabled(E)
+-      ((E) ? "on" : "off")
++      str_on_off(E)
 
-@str_enabled_disabled_r depends on !patch@
+@str_on_off_r depends on !patch@
 expression E;
 position P;
 @@
-*      E@P ? "enabled" : "disabled"
+*      E@P ? "on" : "off"
 
 @script:python depends on report@
-p << str_enabled_disabled_r.P;
-e << str_enabled_disabled_r.E;
+p << str_on_off_r.P;
+e << str_on_off_r.E;
 @@
 
-coccilib.report.print_report(p[0], "opportunity for str_enabled_disabled(%s)" % e)
+coccilib.report.print_report(p[0], "opportunity for str_on_off(%s)" % e)
 
 @str_read_write depends on patch disable neg_if_exp@
 expression E;
@@ -263,24 +216,81 @@ e << str_write_read_r.E;
 
 coccilib.report.print_report(p[0], "opportunity for str_write_read(%s)" % e)
 
-@str_on_off depends on patch@
+@str_true_false depends on patch disable neg_if_exp@
 expression E;
 @@
--      ((E) ? "on" : "off")
-+      str_on_off(E)
+-      ((E) ? "true" : "false")
++      str_true_false(E)
 
-@str_on_off_r depends on !patch@
+@str_true_false_r depends on !patch disable neg_if_exp@
 expression E;
 position P;
 @@
-*      E@P ? "on" : "off"
+*      E@P ? "true" : "false"
 
 @script:python depends on report@
-p << str_on_off_r.P;
-e << str_on_off_r.E;
+p << str_true_false_r.P;
+e << str_true_false_r.E;
 @@
 
-coccilib.report.print_report(p[0], "opportunity for str_on_off(%s)" % e)
+coccilib.report.print_report(p[0], "opportunity for str_true_false(%s)" % e)
+
+@str_false_true depends on patch disable neg_if_exp@
+expression E;
+@@
+-      ((E) ? "false" : "true")
++      str_false_true(E)
+
+@str_false_true_r depends on !patch disable neg_if_exp@
+expression E;
+position P;
+@@
+*      E@P ? "false" : "true"
+
+@script:python depends on report@
+p << str_false_true_r.P;
+e << str_false_true_r.E;
+@@
+
+coccilib.report.print_report(p[0], "opportunity for str_false_true(%s)" % e)
+
+@str_up_down depends on patch disable neg_if_exp@
+expression E;
+@@
+-	((E) ? "up" : "down")
++	str_up_down(E)
+
+@str_up_down_r depends on !patch disable neg_if_exp@
+expression E;
+position P;
+@@
+*	E@P ? "up" : "down"
+
+@script:python depends on report@
+p << str_up_down_r.P;
+e << str_up_down_r.E;
+@@
+
+coccilib.report.print_report(p[0], "opportunity for str_up_down(%s)" % e)
+
+@str_down_up depends on patch disable neg_if_exp@
+expression E;
+@@
+-      ((E) ? "down" : "up")
++      str_down_up(E)
+
+@str_down_up_r depends on !patch disable neg_if_exp@
+expression E;
+position P;
+@@
+*      E@P ? "down" : "up"
+
+@script:python depends on report@
+p << str_down_up_r.P;
+e << str_down_up_r.E;
+@@
+
+coccilib.report.print_report(p[0], "opportunity for str_down_up(%s)" % e)
 
 @str_yes_no depends on patch@
 expression E;
@@ -300,3 +310,31 @@ e << str_yes_no_r.E;
 @@
 
 coccilib.report.print_report(p[0], "opportunity for str_yes_no(%s)" % e)
+
+@str_plural depends on patch@
+expression E;
+@@
+(
+-	((E == 1) ? "" : "s")
++	str_plural(E)
+|
+-	((E > 1) ? "s" : "")
++	str_plural(E)
+)
+
+@str_plural_r depends on !patch@
+expression E;
+position P;
+@@
+(
+*	(E@P == 1) ? "" : "s"
+|
+*	(E@P > 1) ? "s" : ""
+)
+
+@script:python depends on report@
+p << str_plural_r.P;
+e << str_plural_r.E;
+@@
+
+coccilib.report.print_report(p[0], "opportunity for str_plural(%s)" % e)
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 1/2] lib/string_choices: Add str_alloc_free() helper
  2026-04-30  6:40 ` [PATCH v2 1/2] lib/string_choices: Add str_alloc_free() helper Jiazi Li
@ 2026-05-01  8:51   ` Andy Shevchenko
  0 siblings, 0 replies; 6+ messages in thread
From: Andy Shevchenko @ 2026-05-01  8:51 UTC (permalink / raw)
  To: Jiazi Li
  Cc: Kees Cook, Andy Shevchenko, Julia Lawall, Nicolas Palix,
	linux-hardening, mingzhu.wang

On Thu, Apr 30, 2026 at 9:41 AM Jiazi Li <jqqlijiazi@gmail.com> wrote:
>
> Add str_alloc_free() helper to return "alloc" or "free"
> string literal depending on the boolean argument. Also add the
> inversed variant str_free_alloc().

> Suggested-by: Andy Shevchenko <andy@kernel.org>

You are not supposed to randomly put some tags without approval. I
didn't suggest anything to this patch, I *reviewed* the first version
and commented on it, but I have *not* given any tag (neither
Suggested-by, nor Reviewed-by, nor anything else).

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] coccinelle: Add rules to find str_alloc_free() replacements
  2026-04-30  6:40 ` [PATCH v2 2/2] coccinelle: Add rules to find str_alloc_free() replacements Jiazi Li
@ 2026-05-01  8:53   ` Andy Shevchenko
  0 siblings, 0 replies; 6+ messages in thread
From: Andy Shevchenko @ 2026-05-01  8:53 UTC (permalink / raw)
  To: Jiazi Li
  Cc: Kees Cook, Andy Shevchenko, Julia Lawall, Nicolas Palix,
	linux-hardening, mingzhu.wang

On Thu, Apr 30, 2026 at 9:41 AM Jiazi Li <jqqlijiazi@gmail.com> wrote:
>
> Add rules for finding places where str_alloc_free()/str_free_alloc
> can be used.
> This currently finds 4 locations.
>
> Adjust the position of some coccinelle rules, so they sorted in the
> same order as they appear in the header.

...

> Suggested-by: Andy Shevchenko <andy@kernel.org>

I indeed suggested sorting the coccinelle script to follow the order
of appearance of the functions in the C file. However, this patch has
two changes in one, and the second one I have not suggested. So, split
these to two (the first one is sorting one, which may have my
Suggested-by tag, and the second one is adding your new helper).


> V2: Keep coccinelle stances sorted in the same order as they appear in
> the header.


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 0/2] Add str_alloc_free()/str_free_alloc helper and
  2026-04-30  6:40 [PATCH v2 0/2] Add str_alloc_free()/str_free_alloc helper and Jiazi Li
  2026-04-30  6:40 ` [PATCH v2 1/2] lib/string_choices: Add str_alloc_free() helper Jiazi Li
  2026-04-30  6:40 ` [PATCH v2 2/2] coccinelle: Add rules to find str_alloc_free() replacements Jiazi Li
@ 2026-05-01  8:54 ` Andy Shevchenko
  2 siblings, 0 replies; 6+ messages in thread
From: Andy Shevchenko @ 2026-05-01  8:54 UTC (permalink / raw)
  To: Jiazi Li
  Cc: Kees Cook, Andy Shevchenko, Julia Lawall, Nicolas Palix,
	linux-hardening

On Thu, Apr 30, 2026 at 9:41 AM Jiazi Li <jqqlijiazi@gmail.com> wrote:
>
> Currently finds 4 locations:
> ./drivers/net/wireless/realtek/rtw89/fw.c:2557:7-12: opportunity for str_alloc_free(valid)
> ./drivers/net/wireless/realtek/rtw89/fw.c:2693:7-12: opportunity for str_alloc_free(valid)
> ./drivers/android/tests/binder_alloc_kunit.c:196:6-21: opportunity for str_alloc_free(alloc -> pages [ i ])
> ./mm/slub.c:1634:3-8: opportunity for str_alloc_free(alloc)

So, add a first user at least to make sure you haven't added a dead
code, probably rtw89 is the best choice as it has more callsites.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-05-01  8:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-30  6:40 [PATCH v2 0/2] Add str_alloc_free()/str_free_alloc helper and Jiazi Li
2026-04-30  6:40 ` [PATCH v2 1/2] lib/string_choices: Add str_alloc_free() helper Jiazi Li
2026-05-01  8:51   ` Andy Shevchenko
2026-04-30  6:40 ` [PATCH v2 2/2] coccinelle: Add rules to find str_alloc_free() replacements Jiazi Li
2026-05-01  8:53   ` Andy Shevchenko
2026-05-01  8:54 ` [PATCH v2 0/2] Add str_alloc_free()/str_free_alloc helper and Andy Shevchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox