All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/2] Simplify implementation of strscpy()
@ 2026-11-03 13:27 Alejandro Colomar
  2026-11-03 13:27 ` [PATCH v1 1/2] args: Add DEFARG() to implement macro default arguments Alejandro Colomar
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Alejandro Colomar @ 2026-11-03 13:27 UTC (permalink / raw)
  To: Kees Cook, linux-hardening; +Cc: Alejandro Colomar, Andy Shevchenko

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

Hi!

Here's a simpler implementation of the default arguments in strscpy(9).
It avoids having to build concatenated names, the ignored '...' in
__strscpy0, counting arguments, etc.  It's replaced by a quite simple
macro that takes two arguments, and picks the last non-empty one.

It requires a C23 feature, but it's supported as a GNU extension in
GNU C11 mode, and was implemented a long time ago, so it should be fine.


Have a lovely day!
Alex

Alejandro Colomar (2):
  args: Add DEFARG() to implement macro default arguments
  string: Simplify strscpy[_pad]()

 include/linux/args.h   |  5 +++++
 include/linux/string.h | 22 ++++------------------
 2 files changed, 9 insertions(+), 18 deletions(-)

Range-diff against v0:
-:  ------------ > 1:  be1057524eb2 args: Add DEFARG() to implement macro default arguments
-:  ------------ > 2:  31096484d9be string: Simplify strscpy[_pad]()
-- 
2.55.0


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

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

* [PATCH v1 1/2] args: Add DEFARG() to implement macro default arguments
  2026-11-03 13:27 [PATCH v1 0/2] Simplify implementation of strscpy() Alejandro Colomar
@ 2026-11-03 13:27 ` Alejandro Colomar
  2026-11-03 13:31   ` Alejandro Colomar
  2026-11-03 13:27 ` [PATCH v1 2/2] string: Simplify strscpy[_pad]() Alejandro Colomar
  2026-11-03 19:10 ` [PATCH v1 0/2] Simplify implementation of strscpy() Andy Shevchenko
  2 siblings, 1 reply; 6+ messages in thread
From: Alejandro Colomar @ 2026-11-03 13:27 UTC (permalink / raw)
  To: Kees Cook, linux-hardening; +Cc: Alejandro Colomar, Andy Shevchenko

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

It needs __VA_OPT__, which is a C23 feature, but it's provided by GCC
and Clang in GNU-C mode as an extension even without C23.  __VA_OPT__
was implemented in GCC 9 and Clang 6, I think, so it should be widely
available.

Here's a small example program showing how this works:

	alx@devuan:~/tmp$ cat d.c
	#define D__(x, ...)  (x)
	#define D_(x, ...)   D__(__VA_ARGS__ __VA_OPT__(,) x)
	#define D(a, b)      D_(a, b)
	D(1, 2)
	D(1, )
	D(, 2)
	D(,)
	alx@devuan:~/tmp$ gcc -E -Wall -Wextra d.c | grep '^[^#]'
	(2)
	(1)
	(2)
	()

Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
 include/linux/args.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/linux/args.h b/include/linux/args.h
index 0562dc51435e..5886011cf791 100644
--- a/include/linux/args.h
+++ b/include/linux/args.h
@@ -3,6 +3,11 @@
 #ifndef _LINUX_ARGS_H
 #define _LINUX_ARGS_H
 
+/* Expand to 'arg' if non-empty, or to 'def' if 'arg' is empty.  */
+#define ___DEFARG(x, ...)   (x)
+#define __DEFARG(def, ...)  ___DEFARG(__VA_ARGS__ __VA_OPT__(,) def)
+#define DEFARG(def, arg)    __DEFARG(def, arg)
+
 /*
  * How do these macros work?
  *
-- 
2.55.0


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

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

* [PATCH v1 2/2] string: Simplify strscpy[_pad]()
  2026-11-03 13:27 [PATCH v1 0/2] Simplify implementation of strscpy() Alejandro Colomar
  2026-11-03 13:27 ` [PATCH v1 1/2] args: Add DEFARG() to implement macro default arguments Alejandro Colomar
@ 2026-11-03 13:27 ` Alejandro Colomar
  2026-11-03 19:10 ` [PATCH v1 0/2] Simplify implementation of strscpy() Andy Shevchenko
  2 siblings, 0 replies; 6+ messages in thread
From: Alejandro Colomar @ 2026-11-03 13:27 UTC (permalink / raw)
  To: Kees Cook, linux-hardening; +Cc: Alejandro Colomar, Andy Shevchenko

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

Remove the need for intermediate macros and COUNT_ARGS().

Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
 include/linux/string.h | 22 ++++------------------
 1 file changed, 4 insertions(+), 18 deletions(-)

diff --git a/include/linux/string.h b/include/linux/string.h
index 6cb5cdd01158..b17c7b9d8bc9 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -69,22 +69,6 @@ extern char * strcpy(char *,const char *);
 #endif
 ssize_t sized_strscpy(char *, const char *, size_t);
 
-/*
- * The 2 argument style can only be used when dst is an array with a
- * known size.
- */
-#define __strscpy0(dst, src, ...)	\
-	sized_strscpy(dst, src, sizeof(dst) + __must_be_array(dst) +	\
-				__must_be_cstr(dst) + __must_be_cstr(src))
-#define __strscpy1(dst, src, size)	\
-	sized_strscpy(dst, src, size + __must_be_cstr(dst) + __must_be_cstr(src))
-
-#define __strscpy_pad0(dst, src, ...)	\
-	sized_strscpy_pad(dst, src, sizeof(dst) + __must_be_array(dst) +	\
-				    __must_be_cstr(dst) + __must_be_cstr(src))
-#define __strscpy_pad1(dst, src, size)	\
-	sized_strscpy_pad(dst, src, size + __must_be_cstr(dst) + __must_be_cstr(src))
-
 /**
  * strscpy - Copy a C-string into a sized buffer
  * @dst: Where to copy the string to
@@ -108,7 +92,8 @@ ssize_t sized_strscpy(char *, const char *, size_t);
  * truncated.
  */
 #define strscpy(dst, src, ...)	\
-	CONCATENATE(__strscpy, COUNT_ARGS(__VA_ARGS__))(dst, src, __VA_ARGS__)
+	sized_strscpy(dst, src, DEFARG(sizeof(dst) + __must_be_array(dst), __VA_ARGS__) + \
+				__must_be_cstr(dst) + __must_be_cstr(src))
 
 #define sized_strscpy_pad(dest, src, count)	({			\
 	char *__dst = (dest);						\
@@ -143,7 +128,8 @@ ssize_t sized_strscpy(char *, const char *, size_t);
  * * -E2BIG if count is 0 or @src was truncated.
  */
 #define strscpy_pad(dst, src, ...)	\
-	CONCATENATE(__strscpy_pad, COUNT_ARGS(__VA_ARGS__))(dst, src, __VA_ARGS__)
+	sized_strscpy_pad(dst, src, DEFARG(sizeof(dst) + __must_be_array(dst), __VA_ARGS__) + \
+				__must_be_cstr(dst) + __must_be_cstr(src))
 
 #ifndef __HAVE_ARCH_STRCAT
 extern char * strcat(char *, const char *);
-- 
2.55.0


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

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

* Re: [PATCH v1 1/2] args: Add DEFARG() to implement macro default arguments
  2026-11-03 13:27 ` [PATCH v1 1/2] args: Add DEFARG() to implement macro default arguments Alejandro Colomar
@ 2026-11-03 13:31   ` Alejandro Colomar
  0 siblings, 0 replies; 6+ messages in thread
From: Alejandro Colomar @ 2026-11-03 13:31 UTC (permalink / raw)
  To: Kees Cook, linux-hardening; +Cc: Andy Shevchenko

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

> Date: 2026-11-03 14:27:11+0100
> From: Alejandro Colomar <alx@kernel.org>
>
> It needs __VA_OPT__, which is a C23 feature, but it's provided by GCC
> and Clang in GNU-C mode as an extension even without C23.  __VA_OPT__
> was implemented in GCC 9 and Clang 6, I think, so it should be widely

Actually, it seems it was implemented in Clang 12, not Clang 6.
I got that 6 from llvmorg-6.0.0-rc1, but that version number seems to
not be the same as the Clang version number.  Anyway, Clang 12 should be
fine, I think.


Cheers,
Alex

> available.
> 
> Here's a small example program showing how this works:
> 
> 	alx@devuan:~/tmp$ cat d.c
> 	#define D__(x, ...)  (x)
> 	#define D_(x, ...)   D__(__VA_ARGS__ __VA_OPT__(,) x)
> 	#define D(a, b)      D_(a, b)
> 	D(1, 2)
> 	D(1, )
> 	D(, 2)
> 	D(,)
> 	alx@devuan:~/tmp$ gcc -E -Wall -Wextra d.c | grep '^[^#]'
> 	(2)
> 	(1)
> 	(2)
> 	()
> 
> Signed-off-by: Alejandro Colomar <alx@kernel.org>
> ---
>  include/linux/args.h | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/include/linux/args.h b/include/linux/args.h
> index 0562dc51435e..5886011cf791 100644
> --- a/include/linux/args.h
> +++ b/include/linux/args.h
> @@ -3,6 +3,11 @@
>  #ifndef _LINUX_ARGS_H
>  #define _LINUX_ARGS_H
>  
> +/* Expand to 'arg' if non-empty, or to 'def' if 'arg' is empty.  */
> +#define ___DEFARG(x, ...)   (x)
> +#define __DEFARG(def, ...)  ___DEFARG(__VA_ARGS__ __VA_OPT__(,) def)
> +#define DEFARG(def, arg)    __DEFARG(def, arg)
> +
>  /*
>   * How do these macros work?
>   *
> -- 
> 2.55.0
> 



-- 
<https://www.alejandro-colomar.es>

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

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

* Re: [PATCH v1 0/2] Simplify implementation of strscpy()
  2026-11-03 13:27 [PATCH v1 0/2] Simplify implementation of strscpy() Alejandro Colomar
  2026-11-03 13:27 ` [PATCH v1 1/2] args: Add DEFARG() to implement macro default arguments Alejandro Colomar
  2026-11-03 13:27 ` [PATCH v1 2/2] string: Simplify strscpy[_pad]() Alejandro Colomar
@ 2026-11-03 19:10 ` Andy Shevchenko
  2026-11-03 23:21   ` Alejandro Colomar
  2 siblings, 1 reply; 6+ messages in thread
From: Andy Shevchenko @ 2026-11-03 19:10 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: Kees Cook, linux-hardening, Andy Shevchenko

On Tue, Nov 03, 2026 at 02:27:08PM +0100, Alejandro Colomar wrote:
> 
> Here's a simpler implementation of the default arguments in strscpy(9).
> It avoids having to build concatenated names, the ignored '...' in
> __strscpy0, counting arguments, etc.  It's replaced by a quite simple
> macro that takes two arguments, and picks the last non-empty one.
> 
> It requires a C23 feature, but it's supported as a GNU extension in
> GNU C11 mode, and was implemented a long time ago, so it should be fine.

Yes and no.
See 551d44200152 ("default_gfp(): avoid using the "newfangled" __VA_OPT__ trick")
for the details.
So far NAK from me.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH v1 0/2] Simplify implementation of strscpy()
  2026-11-03 19:10 ` [PATCH v1 0/2] Simplify implementation of strscpy() Andy Shevchenko
@ 2026-11-03 23:21   ` Alejandro Colomar
  0 siblings, 0 replies; 6+ messages in thread
From: Alejandro Colomar @ 2026-11-03 23:21 UTC (permalink / raw)
  To: Andy Shevchenko, Chris Li, linux-sparse
  Cc: Alejandro Colomar, Kees Cook, linux-hardening, Andy Shevchenko

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

Hi Andy,

> Date: 2026-11-03 21:10:23+0200
> From: Andy Shevchenko <andriy.shevchenko@intel.com>
>
> On Tue, Nov 03, 2026 at 02:27:08PM +0100, Alejandro Colomar wrote:
> > 
> > Here's a simpler implementation of the default arguments in strscpy(9).
> > It avoids having to build concatenated names, the ignored '...' in
> > __strscpy0, counting arguments, etc.  It's replaced by a quite simple
> > macro that takes two arguments, and picks the last non-empty one.
> > 
> > It requires a C23 feature, but it's supported as a GNU extension in
> > GNU C11 mode, and was implemented a long time ago, so it should be fine.
> 
> Yes and no.
> See 551d44200152 ("default_gfp(): avoid using the "newfangled" __VA_OPT__ trick")
> for the details.

Hmmmm, so sparse is a problem.  DEFARG() cannot be implemented with
##__VA_ARGS__ (I believe), so I think this is frozen until sparse is
improved to add support for __VA_OPT__.

The implementation in that commit you pointed takes advantage of the
fact that the default value is hard-coded in the macro, and the macro
has zero fixed parameters, which makes it work, but if you add one fixed
parameter (which we need for a generic DEFARG() macro), then it doesn't
work.  GCC's ## is quite limited compared to __VA_OPT__().

I've CCed the sparse matinainer and mailing list.  Let's see if they can
add support for __VA_OPT__().

> So far NAK from me.

Makes sense.  Thanks for the review!


Have a lovely night!
Alex

> 
> -- 
> With Best Regards,
> Andy Shevchenko
> 
> 
> 

-- 
<https://www.alejandro-colomar.es>

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

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

end of thread, other threads:[~2026-11-03 23:21 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-03 13:27 [PATCH v1 0/2] Simplify implementation of strscpy() Alejandro Colomar
2026-11-03 13:27 ` [PATCH v1 1/2] args: Add DEFARG() to implement macro default arguments Alejandro Colomar
2026-11-03 13:31   ` Alejandro Colomar
2026-11-03 13:27 ` [PATCH v1 2/2] string: Simplify strscpy[_pad]() Alejandro Colomar
2026-11-03 19:10 ` [PATCH v1 0/2] Simplify implementation of strscpy() Andy Shevchenko
2026-11-03 23:21   ` Alejandro Colomar

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.