From a98ae7f045b29de4f48b191d5aeb4e803183d759 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Thu, 25 Jul 2024 12:18:40 +0200 Subject: lib/string_choices: Add str_up_down() helper Add str_up_down() helper to return "up" or "down" string literal. Signed-off-by: Michal Wajdeczko Link: https://lore.kernel.org/r/20240725101841.574-1-michal.wajdeczko@intel.com Signed-off-by: Kees Cook --- include/linux/string_choices.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/string_choices.h b/include/linux/string_choices.h index d9ebe20229f8..bcde3c9cff81 100644 --- a/include/linux/string_choices.h +++ b/include/linux/string_choices.h @@ -42,6 +42,11 @@ static inline const char *str_yes_no(bool v) return v ? "yes" : "no"; } +static inline const char *str_up_down(bool v) +{ + return v ? "up" : "down"; +} + /** * str_plural - Return the simple pluralization based on English counts * @num: Number used for deciding pluralization -- cgit v1.2.3 From f5c1ca3a15fdb867d2b535003f74e0b975eff116 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 12 Aug 2024 11:29:40 -0700 Subject: string_choices: Add wrapper for str_down_up() The string choice functions which are not clearly true/false synonyms also have inverted wrappers. Add this for str_down_up() as well. Suggested-by: Andy Shevchenko Link: https://lore.kernel.org/r/20240812182939.work.424-kees@kernel.org Reviewed-by: Andy Shevchenko Signed-off-by: Kees Cook --- include/linux/string_choices.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/string_choices.h b/include/linux/string_choices.h index bcde3c9cff81..1320bcdcb89c 100644 --- a/include/linux/string_choices.h +++ b/include/linux/string_choices.h @@ -46,6 +46,7 @@ static inline const char *str_up_down(bool v) { return v ? "up" : "down"; } +#define str_down_up(v) str_up_down(!(v)) /** * str_plural - Return the simple pluralization based on English counts -- cgit v1.2.3 From 5ac86f0ed04bce41242167ffa12ad92038788a95 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 10 Jul 2024 16:15:55 -0700 Subject: virt: vbox: struct vmmdev_hgcm_pagelist: Replace 1-element array with flexible array Replace the deprecated[1] use of a 1-element array in struct vmmdev_hgcm_pagelist with a modern flexible array. As this is UAPI, we cannot trivially change the size of the struct, so use a union to retain the old first element's size, but switch "pages" to a flexible array. No binary differences are present after this conversion. Link: https://github.com/KSPP/linux/issues/79 [1] Reviewed-by: Gustavo A. R. Silva Link: https://lore.kernel.org/r/20240710231555.work.406-kees@kernel.org Signed-off-by: Kees Cook --- include/uapi/linux/vbox_vmmdev_types.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/uapi/linux/vbox_vmmdev_types.h b/include/uapi/linux/vbox_vmmdev_types.h index f8a8d6b3c521..6073858d52a2 100644 --- a/include/uapi/linux/vbox_vmmdev_types.h +++ b/include/uapi/linux/vbox_vmmdev_types.h @@ -282,7 +282,10 @@ struct vmmdev_hgcm_pagelist { __u32 flags; /** VMMDEV_HGCM_F_PARM_*. */ __u16 offset_first_page; /** Data offset in the first page. */ __u16 page_count; /** Number of pages. */ - __u64 pages[1]; /** Page addresses. */ + union { + __u64 unused; /** Deprecated place-holder for first "pages" entry. */ + __DECLARE_FLEX_ARRAY(__u64, pages); /** Page addresses. */ + }; }; VMMDEV_ASSERT_SIZE(vmmdev_hgcm_pagelist, 4 + 2 + 2 + 8); -- cgit v1.2.3 From 559048d156ff3391c4b793779a824c9193e20442 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 5 Aug 2024 14:43:44 -0700 Subject: string: Check for "nonstring" attribute on strscpy() arguments GCC already checks for arguments that are marked with the "nonstring"[1] attribute when used on standard C String API functions (e.g. strcpy). Gain this compile-time checking also for the kernel's primary string copying function, strscpy(). Note that Clang has neither "nonstring" nor __builtin_has_attribute(). Link: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-nonstring-variable-attribute [1] Reviewed-by: Miguel Ojeda Tested-by: Miguel Ojeda Link: https://lore.kernel.org/r/20240805214340.work.339-kees@kernel.org Signed-off-by: Kees Cook --- include/linux/compiler.h | 3 +++ include/linux/compiler_types.h | 7 +++++++ include/linux/string.h | 12 ++++++++---- 3 files changed, 18 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 2df665fa2964..ec55bcce4146 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -242,6 +242,9 @@ static inline void *offset_to_ptr(const int *off) /* &a[0] degrades to a pointer: a different type from an array */ #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) +/* Require C Strings (i.e. NUL-terminated) lack the "nonstring" attribute. */ +#define __must_be_cstr(p) BUILD_BUG_ON_ZERO(__annotated(p, nonstring)) + /* * This returns a constant expression while determining if an argument is * a constant expression, most importantly without evaluating the argument. diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index f14c275950b5..1a957ea2f4fe 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -421,6 +421,13 @@ struct ftrace_likely_data { #define __member_size(p) __builtin_object_size(p, 1) #endif +/* Determine if an attribute has been applied to a variable. */ +#if __has_builtin(__builtin_has_attribute) +#define __annotated(var, attr) __builtin_has_attribute(var, attr) +#else +#define __annotated(var, attr) (false) +#endif + /* * Some versions of gcc do not mark 'asm goto' volatile: * diff --git a/include/linux/string.h b/include/linux/string.h index 9edace076ddb..95b3fc308f4f 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -76,12 +76,16 @@ ssize_t sized_strscpy(char *, const char *, size_t); * known size. */ #define __strscpy0(dst, src, ...) \ - sized_strscpy(dst, src, sizeof(dst) + __must_be_array(dst)) -#define __strscpy1(dst, src, size) sized_strscpy(dst, src, size) + 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)) -#define __strscpy_pad1(dst, src, size) sized_strscpy_pad(dst, src, size) + 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 -- cgit v1.2.3 From 6ff4cd1160afafc12ad1603e3d2f39256e4b708d Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Tue, 27 Aug 2024 10:45:15 +0800 Subject: lib/string_choices: Add str_true_false()/str_false_true() helper Add str_true_false()/str_false_true() helper to return "true" or "false" string literal. Signed-off-by: Hongbo Li Link: https://lore.kernel.org/r/20240827024517.914100-2-lihongbo22@huawei.com Signed-off-by: Kees Cook --- include/linux/string_choices.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/linux/string_choices.h b/include/linux/string_choices.h index 1320bcdcb89c..ebcc56b28ede 100644 --- a/include/linux/string_choices.h +++ b/include/linux/string_choices.h @@ -48,6 +48,12 @@ static inline const char *str_up_down(bool v) } #define str_down_up(v) str_up_down(!(v)) +static inline const char *str_true_false(bool v) +{ + return v ? "true" : "false"; +} +#define str_false_true(v) str_true_false(!(v)) + /** * str_plural - Return the simple pluralization based on English counts * @num: Number used for deciding pluralization -- cgit v1.2.3 From c2708ba91c3c1fba424b77de83b6fc45cbf38c46 Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Thu, 5 Sep 2024 17:25:39 +0800 Subject: lib/string_choices: Introduce several opposite string choice helpers Similar to the exists helper: str_enable_disable/ str_enabled_disabled/str_on_off/str_yes_no helpers, we can add the opposite helpers. That's str_disable_enable, str_disabled_enabled, str_off_on and str_no_yes. There are more than 10 cases currently (expect str_disable_enable now has 3 use cases) exist in the code can be replaced with these helper. Signed-off-by: Hongbo Li Acked-by: Andy Shevchenko Link: https://lore.kernel.org/r/20240905092540.2962122-2-lihongbo22@huawei.com Signed-off-by: Kees Cook --- include/linux/string_choices.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/string_choices.h b/include/linux/string_choices.h index ebcc56b28ede..fd067992260a 100644 --- a/include/linux/string_choices.h +++ b/include/linux/string_choices.h @@ -8,11 +8,13 @@ static inline const char *str_enable_disable(bool v) { return v ? "enable" : "disable"; } +#define str_disable_enable(v) str_enable_disable(!(v)) static inline const char *str_enabled_disabled(bool v) { return v ? "enabled" : "disabled"; } +#define str_disabled_enabled(v) str_enabled_disabled(!(v)) static inline const char *str_hi_lo(bool v) { @@ -36,11 +38,13 @@ static inline const char *str_on_off(bool v) { return v ? "on" : "off"; } +#define str_off_on(v) str_on_off(!(v)) static inline const char *str_yes_no(bool v) { return v ? "yes" : "no"; } +#define str_no_yes(v) str_yes_no(!(v)) static inline const char *str_up_down(bool v) { -- cgit v1.2.3 From c121d5cc3a993cdbfab46a152bdd50227a4d5e8c Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Thu, 5 Sep 2024 17:25:40 +0800 Subject: lib/string_choices: Add some comments to make more clear for string choices helpers. Add some comments to explain why we should use string_choices helpers. Signed-off-by: Hongbo Li Acked-by: Andy Shevchenko Link: https://lore.kernel.org/r/20240905092540.2962122-3-lihongbo22@huawei.com Signed-off-by: Kees Cook --- include/linux/string_choices.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include') diff --git a/include/linux/string_choices.h b/include/linux/string_choices.h index fd067992260a..120ca0f28e95 100644 --- a/include/linux/string_choices.h +++ b/include/linux/string_choices.h @@ -2,6 +2,19 @@ #ifndef _LINUX_STRING_CHOICES_H_ #define _LINUX_STRING_CHOICES_H_ +/* + * Here provide a series of helpers in the str_$TRUE_$FALSE format (you can + * also expand some helpers as needed), where $TRUE and $FALSE are their + * corresponding literal strings. These helpers can be used in the printing + * and also in other places where constant strings are required. Using these + * helpers offers the following benefits: + * 1) Reducing the hardcoding of strings, which makes the code more elegant + * through these simple literal-meaning helpers. + * 2) Unifying the output, which prevents the same string from being printed + * in various forms, such as enable/disable, enabled/disabled, en/dis. + * 3) Deduping by the linker, which results in a smaller binary file. + */ + #include static inline const char *str_enable_disable(bool v) -- cgit v1.2.3