Commit 4be240b1 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'memcpy-v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull FORTIFY_SOURCE updates from Kees Cook:
 "This series consists of two halves:

   - strict compile-time buffer size checking under FORTIFY_SOURCE for
     the memcpy()-family of functions (for extensive details and
     rationale, see the first commit)

   - enabling FORTIFY_SOURCE for Clang, which has had many overlapping
     bugs that we've finally worked past"

* tag 'memcpy-v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  fortify: Add Clang support
  fortify: Make sure strlen() may still be used as a constant expression
  fortify: Use __diagnose_as() for better diagnostic coverage
  fortify: Make pointer arguments const
  Compiler Attributes: Add __diagnose_as for Clang
  Compiler Attributes: Add __overloadable for Clang
  Compiler Attributes: Add __pass_object_size for Clang
  fortify: Replace open-coded __gnu_inline attribute
  fortify: Update compile-time tests for Clang 14
  fortify: Detect struct member overflows in memset() at compile-time
  fortify: Detect struct member overflows in memmove() at compile-time
  fortify: Detect struct member overflows in memcpy() at compile-time
parents 3f728213 281d0c96
...@@ -37,10 +37,11 @@ ...@@ -37,10 +37,11 @@
* try to define their own functions if these are not defined as macros. * try to define their own functions if these are not defined as macros.
*/ */
#define memzero(s, n) memset((s), 0, (n)) #define memzero(s, n) memset((s), 0, (n))
#ifndef memmove
#define memmove memmove #define memmove memmove
/* Functions used by the included decompressor code below. */ /* Functions used by the included decompressor code below. */
void *memmove(void *dest, const void *src, size_t n); void *memmove(void *dest, const void *src, size_t n);
#endif
/* /*
* This is set up by the setup-routine at boot-time * This is set up by the setup-routine at boot-time
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#undef memcpy #undef memcpy
#undef memset #undef memset
#undef memmove
__visible void *memcpy(void *to, const void *from, size_t n) __visible void *memcpy(void *to, const void *from, size_t n)
{ {
......
...@@ -100,6 +100,19 @@ ...@@ -100,6 +100,19 @@
# define __copy(symbol) # define __copy(symbol)
#endif #endif
/*
* Optional: not supported by gcc
* Optional: only supported since clang >= 14.0
* Optional: not supported by icc
*
* clang: https://clang.llvm.org/docs/AttributeReference.html#diagnose_as_builtin
*/
#if __has_attribute(__diagnose_as_builtin__)
# define __diagnose_as(builtin...) __attribute__((__diagnose_as_builtin__(builtin)))
#else
# define __diagnose_as(builtin...)
#endif
/* /*
* Don't. Just don't. See commit 771c035372a0 ("deprecate the '__deprecated' * Don't. Just don't. See commit 771c035372a0 ("deprecate the '__deprecated'
* attribute warnings entirely and for good") for more information. * attribute warnings entirely and for good") for more information.
...@@ -257,12 +270,38 @@ ...@@ -257,12 +270,38 @@
*/ */
#define __noreturn __attribute__((__noreturn__)) #define __noreturn __attribute__((__noreturn__))
/*
* Optional: not supported by gcc.
* Optional: not supported by icc.
*
* clang: https://clang.llvm.org/docs/AttributeReference.html#overloadable
*/
#if __has_attribute(__overloadable__)
# define __overloadable __attribute__((__overloadable__))
#else
# define __overloadable
#endif
/* /*
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute
* clang: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-packed-variable-attribute * clang: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-packed-variable-attribute
*/ */
#define __packed __attribute__((__packed__)) #define __packed __attribute__((__packed__))
/*
* Note: the "type" argument should match any __builtin_object_size(p, type) usage.
*
* Optional: not supported by gcc.
* Optional: not supported by icc.
*
* clang: https://clang.llvm.org/docs/AttributeReference.html#pass-object-size-pass-dynamic-object-size
*/
#if __has_attribute(__pass_object_size__)
# define __pass_object_size(type) __attribute__((__pass_object_size__(type)))
#else
# define __pass_object_size(type)
#endif
/* /*
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute
*/ */
......
This diff is collapsed.
...@@ -377,7 +377,8 @@ TEST_FORTIFY_LOG = test_fortify.log ...@@ -377,7 +377,8 @@ TEST_FORTIFY_LOG = test_fortify.log
quiet_cmd_test_fortify = TEST $@ quiet_cmd_test_fortify = TEST $@
cmd_test_fortify = $(CONFIG_SHELL) $(srctree)/scripts/test_fortify.sh \ cmd_test_fortify = $(CONFIG_SHELL) $(srctree)/scripts/test_fortify.sh \
$< $@ "$(NM)" $(CC) $(c_flags) \ $< $@ "$(NM)" $(CC) $(c_flags) \
$(call cc-disable-warning,fortify-source) $(call cc-disable-warning,fortify-source) \
-DKBUILD_EXTRA_WARN1
targets += $(TEST_FORTIFY_LOGS) targets += $(TEST_FORTIFY_LOGS)
clean-files += $(TEST_FORTIFY_LOGS) clean-files += $(TEST_FORTIFY_LOGS)
......
...@@ -968,6 +968,12 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count, ...@@ -968,6 +968,12 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
EXPORT_SYMBOL(memcpy_and_pad); EXPORT_SYMBOL(memcpy_and_pad);
#ifdef CONFIG_FORTIFY_SOURCE #ifdef CONFIG_FORTIFY_SOURCE
/* These are placeholders for fortify compile-time warnings. */
void __read_overflow2_field(size_t avail, size_t wanted) { }
EXPORT_SYMBOL(__read_overflow2_field);
void __write_overflow_field(size_t avail, size_t wanted) { }
EXPORT_SYMBOL(__write_overflow_field);
void fortify_panic(const char *name) void fortify_panic(const char *name)
{ {
pr_emerg("detected buffer overflow in %s\n", name); pr_emerg("detected buffer overflow in %s\n", name);
......
// SPDX-License-Identifier: GPL-2.0-only
#define TEST \
memcpy(large, instance.buf, sizeof(instance.buf) + 1)
#include "test_fortify.h"
// SPDX-License-Identifier: GPL-2.0-only
#define TEST \
memmove(large, instance.buf, sizeof(instance.buf) + 1)
#include "test_fortify.h"
// SPDX-License-Identifier: GPL-2.0-only
#define TEST \
memcpy(instance.buf, large, sizeof(instance.buf) + 1)
#include "test_fortify.h"
// SPDX-License-Identifier: GPL-2.0-only
#define TEST \
memmove(instance.buf, large, sizeof(instance.buf) + 1)
#include "test_fortify.h"
// SPDX-License-Identifier: GPL-2.0-only
#define TEST \
memset(instance.buf, 0x42, sizeof(instance.buf) + 1)
#include "test_fortify.h"
...@@ -46,8 +46,12 @@ if "$@" -Werror -c "$IN" -o "$OUT".o 2> "$TMP" ; then ...@@ -46,8 +46,12 @@ if "$@" -Werror -c "$IN" -o "$OUT".o 2> "$TMP" ; then
status="warning: unsafe ${FUNC}() usage lacked '$WANT' symbol in $IN" status="warning: unsafe ${FUNC}() usage lacked '$WANT' symbol in $IN"
fi fi
else else
# If the build failed, check for the warning in the stderr (gcc). # If the build failed, check for the warning in the stderr.
if ! grep -q -m1 "error: call to .\b${WANT}\b." "$TMP" ; then # GCC:
# ./include/linux/fortify-string.h:316:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror=attribute-warning]
# Clang 14:
# ./include/linux/fortify-string.h:316:4: error: call to __write_overflow_field declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror,-Wattribute-warning]
if ! grep -Eq -m1 "error: call to .?\b${WANT}\b.?" "$TMP" ; then
status="warning: unsafe ${FUNC}() usage lacked '$WANT' warning in $IN" status="warning: unsafe ${FUNC}() usage lacked '$WANT' warning in $IN"
fi fi
fi fi
......
...@@ -177,9 +177,10 @@ config HARDENED_USERCOPY_PAGESPAN ...@@ -177,9 +177,10 @@ config HARDENED_USERCOPY_PAGESPAN
config FORTIFY_SOURCE config FORTIFY_SOURCE
bool "Harden common str/mem functions against buffer overflows" bool "Harden common str/mem functions against buffer overflows"
depends on ARCH_HAS_FORTIFY_SOURCE depends on ARCH_HAS_FORTIFY_SOURCE
# https://bugs.llvm.org/show_bug.cgi?id=50322
# https://bugs.llvm.org/show_bug.cgi?id=41459 # https://bugs.llvm.org/show_bug.cgi?id=41459
depends on !CC_IS_CLANG depends on !CC_IS_CLANG || CLANG_VERSION >= 120001
# https://github.com/llvm/llvm-project/issues/53645
depends on !CC_IS_CLANG || !X86_32
help help
Detect overflows of buffers in common string and memory functions Detect overflows of buffers in common string and memory functions
where the compiler can determine and validate the buffer sizes. where the compiler can determine and validate the buffer sizes.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment