Skip to content

Commit

Permalink
fortify: Make sure strlen() may still be used as a constant expression
Browse files Browse the repository at this point in the history
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/202201252321.dRmWZ8wW-lkp@intel.com/

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 <keescook@chromium.org>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Link: https://lore.kernel.org/r/20220208225350.1331628-8-keescook@chromium.org
  • Loading branch information
Kees Cook committed Feb 14, 2022
1 parent 92df138 commit 67ebc3a
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions include/linux/fortify-string.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#ifndef _LINUX_FORTIFY_STRING_H_
#define _LINUX_FORTIFY_STRING_H_

#include <linux/const.h>

#define __FORTIFY_INLINE extern __always_inline __gnu_inline
#define __RENAME(x) __asm__(#x)

Expand Down Expand Up @@ -95,9 +97,16 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const p, __kernel_size_t m
return ret;
}

/* defined after fortified strnlen to reuse it. */
/*
* Defined after fortified strnlen to reuse it. However, it must still be
* possible for strlen() to be used on compile-time strings for use in
* static initializers (i.e. as a constant expression).
*/
#define strlen(p) \
__builtin_choose_expr(__is_constexpr(__builtin_strlen(p)), \
__builtin_strlen(p), __fortify_strlen(p))
__FORTIFY_INLINE __diagnose_as(__builtin_strlen, 1)
__kernel_size_t strlen(const char * const p)
__kernel_size_t __fortify_strlen(const char * const p)
{
__kernel_size_t ret;
size_t p_size = __builtin_object_size(p, 1);
Expand Down

0 comments on commit 67ebc3a

Please sign in to comment.