Skip to content

Commit 94a77b3

Browse files
keescat658011
authored andcommitted
fortify: Make sure strlen() may still be used as a constant expression
In preparation for enabling Clang FORTIFY_SOURCE support, redefine strlen() as a macro that tests for being a constant expression so that strlen() can still be used in static initializers, which is lost when adding __pass_object_size and __overloadable. An example of this usage can be seen here: https://lore.kernel.org/all/[email protected]/ Notably, this constant expression feature of strlen() is not available for architectures that build with -ffreestanding. This means the kernel currently does not universally expect strlen() to be used this way, but since there _are_ some build configurations that depend on it, retain the characteristic for Clang FORTIFY_SOURCE builds too. Signed-off-by: Kees Cook <[email protected]> Reviewed-by: Nick Desaulniers <[email protected]> Link: https://lore.kernel.org/r/[email protected] Change-Id: I6e923da259a96fc286cda77c9bd9c6bcf4ca82ff [dereference23: Backport to 4.14] Signed-off-by: Alexander Winkowski <[email protected]> Signed-off-by: onettboots <[email protected]>
1 parent dca3dc7 commit 94a77b3

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

include/linux/fortify-string.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,24 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const p, __kernel_size_t m
9595
return ret;
9696
}
9797

98-
/* defined after fortified strnlen to reuse it. */
98+
/*
99+
* This returns a constant expression while determining if an argument is
100+
* a constant expression, most importantly without evaluating the argument.
101+
* Glory to Martin Uecker <[email protected]>
102+
*/
103+
#define __is_constexpr(x) \
104+
(sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8)))
105+
106+
/*
107+
* Defined after fortified strnlen to reuse it. However, it must still be
108+
* possible for strlen() to be used on compile-time strings for use in
109+
* static initializers (i.e. as a constant expression).
110+
*/
111+
#define strlen(p) \
112+
__builtin_choose_expr(__is_constexpr(__builtin_strlen(p)), \
113+
__builtin_strlen(p), __fortify_strlen(p))
99114
__FORTIFY_INLINE __diagnose_as(__builtin_strlen, 1)
100-
__kernel_size_t strlen(const char * const p)
115+
__kernel_size_t __fortify_strlen(const char * const p)
101116
{
102117
__kernel_size_t ret;
103118
size_t p_size = __builtin_object_size(p, 1);

0 commit comments

Comments
 (0)