* [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.