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