Commit 4be240b1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -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
+1 −0
Original line number Original line Diff line number Diff line
@@ -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)
{
{
+39 −0
Original line number Original line Diff line number Diff line
@@ -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 @@
 */
 */
#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
 */
 */
+188 −50
Original line number Original line Diff line number Diff line
@@ -2,13 +2,17 @@
#ifndef _LINUX_FORTIFY_STRING_H_
#ifndef _LINUX_FORTIFY_STRING_H_
#define _LINUX_FORTIFY_STRING_H_
#define _LINUX_FORTIFY_STRING_H_


#define __FORTIFY_INLINE extern __always_inline __attribute__((gnu_inline))
#include <linux/const.h>

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


void fortify_panic(const char *name) __noreturn __cold;
void fortify_panic(const char *name) __noreturn __cold;
void __read_overflow(void) __compiletime_error("detected read beyond size of object (1st parameter)");
void __read_overflow(void) __compiletime_error("detected read beyond size of object (1st parameter)");
void __read_overflow2(void) __compiletime_error("detected read beyond size of object (2nd parameter)");
void __read_overflow2(void) __compiletime_error("detected read beyond size of object (2nd parameter)");
void __read_overflow2_field(size_t avail, size_t wanted) __compiletime_warning("detected read beyond size of field (2nd parameter); maybe use struct_group()?");
void __write_overflow(void) __compiletime_error("detected write beyond size of object (1st parameter)");
void __write_overflow(void) __compiletime_error("detected write beyond size of object (1st parameter)");
void __write_overflow_field(size_t avail, size_t wanted) __compiletime_warning("detected write beyond size of field (1st parameter); maybe use struct_group()?");


#define __compiletime_strlen(p)					\
#define __compiletime_strlen(p)					\
({								\
({								\
@@ -48,7 +52,17 @@ extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size)
#define __underlying_strncpy	__builtin_strncpy
#define __underlying_strncpy	__builtin_strncpy
#endif
#endif


__FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size)
/*
 * Clang's use of __builtin_object_size() within inlines needs hinting via
 * __pass_object_size(). The preference is to only ever use type 1 (member
 * size, rather than struct size), but there remain some stragglers using
 * type 0 that will be converted in the future.
 */
#define POS	__pass_object_size(1)
#define POS0	__pass_object_size(0)

__FORTIFY_INLINE __diagnose_as(__builtin_strncpy, 1, 2, 3)
char *strncpy(char * const POS p, const char *q, __kernel_size_t size)
{
{
	size_t p_size = __builtin_object_size(p, 1);
	size_t p_size = __builtin_object_size(p, 1);


@@ -59,7 +73,8 @@ __FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size)
	return __underlying_strncpy(p, q, size);
	return __underlying_strncpy(p, q, size);
}
}


__FORTIFY_INLINE char *strcat(char *p, const char *q)
__FORTIFY_INLINE __diagnose_as(__builtin_strcat, 1, 2)
char *strcat(char * const POS p, const char *q)
{
{
	size_t p_size = __builtin_object_size(p, 1);
	size_t p_size = __builtin_object_size(p, 1);


@@ -71,7 +86,7 @@ __FORTIFY_INLINE char *strcat(char *p, const char *q)
}
}


extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen);
extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen);
__FORTIFY_INLINE __kernel_size_t strnlen(const char *p, __kernel_size_t maxlen)
__FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size_t maxlen)
{
{
	size_t p_size = __builtin_object_size(p, 1);
	size_t p_size = __builtin_object_size(p, 1);
	size_t p_len = __compiletime_strlen(p);
	size_t p_len = __compiletime_strlen(p);
@@ -91,8 +106,16 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char *p, __kernel_size_t maxlen)
	return ret;
	return ret;
}
}


/* defined after fortified strnlen to reuse it. */
/*
__FORTIFY_INLINE __kernel_size_t strlen(const char *p)
 * 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 __fortify_strlen(const char * const POS p)
{
{
	__kernel_size_t ret;
	__kernel_size_t ret;
	size_t p_size = __builtin_object_size(p, 1);
	size_t p_size = __builtin_object_size(p, 1);
@@ -108,7 +131,7 @@ __FORTIFY_INLINE __kernel_size_t strlen(const char *p)


/* defined after fortified strlen to reuse it */
/* defined after fortified strlen to reuse it */
extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy);
extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy);
__FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size)
__FORTIFY_INLINE size_t strlcpy(char * const POS p, const char * const POS q, size_t size)
{
{
	size_t p_size = __builtin_object_size(p, 1);
	size_t p_size = __builtin_object_size(p, 1);
	size_t q_size = __builtin_object_size(q, 1);
	size_t q_size = __builtin_object_size(q, 1);
@@ -135,7 +158,7 @@ __FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size)


/* defined after fortified strnlen to reuse it */
/* defined after fortified strnlen to reuse it */
extern ssize_t __real_strscpy(char *, const char *, size_t) __RENAME(strscpy);
extern ssize_t __real_strscpy(char *, const char *, size_t) __RENAME(strscpy);
__FORTIFY_INLINE ssize_t strscpy(char *p, const char *q, size_t size)
__FORTIFY_INLINE ssize_t strscpy(char * const POS p, const char * const POS q, size_t size)
{
{
	size_t len;
	size_t len;
	/* Use string size rather than possible enclosing struct size. */
	/* Use string size rather than possible enclosing struct size. */
@@ -181,7 +204,8 @@ __FORTIFY_INLINE ssize_t strscpy(char *p, const char *q, size_t size)
}
}


/* defined after fortified strlen and strnlen to reuse them */
/* defined after fortified strlen and strnlen to reuse them */
__FORTIFY_INLINE char *strncat(char *p, const char *q, __kernel_size_t count)
__FORTIFY_INLINE __diagnose_as(__builtin_strncat, 1, 2, 3)
char *strncat(char * const POS p, const char * const POS q, __kernel_size_t count)
{
{
	size_t p_len, copy_len;
	size_t p_len, copy_len;
	size_t p_size = __builtin_object_size(p, 1);
	size_t p_size = __builtin_object_size(p, 1);
@@ -198,51 +222,161 @@ __FORTIFY_INLINE char *strncat(char *p, const char *q, __kernel_size_t count)
	return p;
	return p;
}
}


__FORTIFY_INLINE void *memset(void *p, int c, __kernel_size_t size)
__FORTIFY_INLINE void fortify_memset_chk(__kernel_size_t size,
					 const size_t p_size,
					 const size_t p_size_field)
{
{
	size_t p_size = __builtin_object_size(p, 0);
	if (__builtin_constant_p(size)) {
		/*
		 * Length argument is a constant expression, so we
		 * can perform compile-time bounds checking where
		 * buffer sizes are known.
		 */


	if (__builtin_constant_p(size) && p_size < size)
		/* Error when size is larger than enclosing struct. */
		if (p_size > p_size_field && p_size < size)
			__write_overflow();
			__write_overflow();
	if (p_size < size)
		fortify_panic(__func__);
	return __underlying_memset(p, c, size);
}


__FORTIFY_INLINE void *memcpy(void *p, const void *q, __kernel_size_t size)
		/* Warn when write size is larger than dest field. */
{
		if (p_size_field < size)
	size_t p_size = __builtin_object_size(p, 0);
			__write_overflow_field(p_size_field, size);
	size_t q_size = __builtin_object_size(q, 0);

	if (__builtin_constant_p(size)) {
		if (p_size < size)
			__write_overflow();
		if (q_size < size)
			__read_overflow2();
	}
	}
	if (p_size < size || q_size < size)
	/*
		fortify_panic(__func__);
	 * At this point, length argument may not be a constant expression,
	return __underlying_memcpy(p, q, size);
	 * so run-time bounds checking can be done where buffer sizes are
	 * known. (This is not an "else" because the above checks may only
	 * be compile-time warnings, and we want to still warn for run-time
	 * overflows.)
	 */

	/*
	 * Always stop accesses beyond the struct that contains the
	 * field, when the buffer's remaining size is known.
	 * (The -1 test is to optimize away checks where the buffer
	 * lengths are unknown.)
	 */
	if (p_size != (size_t)(-1) && p_size < size)
		fortify_panic("memset");
}
}


__FORTIFY_INLINE void *memmove(void *p, const void *q, __kernel_size_t size)
#define __fortify_memset_chk(p, c, size, p_size, p_size_field) ({	\
{
	size_t __fortify_size = (size_t)(size);				\
	size_t p_size = __builtin_object_size(p, 0);
	fortify_memset_chk(__fortify_size, p_size, p_size_field),	\
	size_t q_size = __builtin_object_size(q, 0);
	__underlying_memset(p, c, __fortify_size);			\
})

/*
 * __builtin_object_size() must be captured here to avoid evaluating argument
 * side-effects further into the macro layers.
 */
#define memset(p, c, s) __fortify_memset_chk(p, c, s,			\
		__builtin_object_size(p, 0), __builtin_object_size(p, 1))


/*
 * To make sure the compiler can enforce protection against buffer overflows,
 * memcpy(), memmove(), and memset() must not be used beyond individual
 * struct members. If you need to copy across multiple members, please use
 * struct_group() to create a named mirror of an anonymous struct union.
 * (e.g. see struct sk_buff.) Read overflow checking is currently only
 * done when a write overflow is also present, or when building with W=1.
 *
 * Mitigation coverage matrix
 *					Bounds checking at:
 *					+-------+-------+-------+-------+
 *					| Compile time  |   Run time    |
 * memcpy() argument sizes:		| write | read  | write | read  |
 *        dest     source   length      +-------+-------+-------+-------+
 * memcpy(known,   known,   constant)	|   y   |   y   |  n/a  |  n/a  |
 * memcpy(known,   unknown, constant)	|   y   |   n   |  n/a  |   V   |
 * memcpy(known,   known,   dynamic)	|   n   |   n   |   B   |   B   |
 * memcpy(known,   unknown, dynamic)	|   n   |   n   |   B   |   V   |
 * memcpy(unknown, known,   constant)	|   n   |   y   |   V   |  n/a  |
 * memcpy(unknown, unknown, constant)	|   n   |   n   |   V   |   V   |
 * memcpy(unknown, known,   dynamic)	|   n   |   n   |   V   |   B   |
 * memcpy(unknown, unknown, dynamic)	|   n   |   n   |   V   |   V   |
 *					+-------+-------+-------+-------+
 *
 * y = perform deterministic compile-time bounds checking
 * n = cannot perform deterministic compile-time bounds checking
 * n/a = no run-time bounds checking needed since compile-time deterministic
 * B = can perform run-time bounds checking (currently unimplemented)
 * V = vulnerable to run-time overflow (will need refactoring to solve)
 *
 */
__FORTIFY_INLINE void fortify_memcpy_chk(__kernel_size_t size,
					 const size_t p_size,
					 const size_t q_size,
					 const size_t p_size_field,
					 const size_t q_size_field,
					 const char *func)
{
	if (__builtin_constant_p(size)) {
	if (__builtin_constant_p(size)) {
		if (p_size < size)
		/*
		 * Length argument is a constant expression, so we
		 * can perform compile-time bounds checking where
		 * buffer sizes are known.
		 */

		/* Error when size is larger than enclosing struct. */
		if (p_size > p_size_field && p_size < size)
			__write_overflow();
			__write_overflow();
		if (q_size < size)
		if (q_size > q_size_field && q_size < size)
			__read_overflow2();
			__read_overflow2();

		/* Warn when write size argument larger than dest field. */
		if (p_size_field < size)
			__write_overflow_field(p_size_field, size);
		/*
		 * Warn for source field over-read when building with W=1
		 * or when an over-write happened, so both can be fixed at
		 * the same time.
		 */
		if ((IS_ENABLED(KBUILD_EXTRA_WARN1) || p_size_field < size) &&
		    q_size_field < size)
			__read_overflow2_field(q_size_field, size);
	}
	}
	if (p_size < size || q_size < size)
	/*
		fortify_panic(__func__);
	 * At this point, length argument may not be a constant expression,
	return __underlying_memmove(p, q, size);
	 * so run-time bounds checking can be done where buffer sizes are
	 * known. (This is not an "else" because the above checks may only
	 * be compile-time warnings, and we want to still warn for run-time
	 * overflows.)
	 */

	/*
	 * Always stop accesses beyond the struct that contains the
	 * field, when the buffer's remaining size is known.
	 * (The -1 test is to optimize away checks where the buffer
	 * lengths are unknown.)
	 */
	if ((p_size != (size_t)(-1) && p_size < size) ||
	    (q_size != (size_t)(-1) && q_size < size))
		fortify_panic(func);
}
}


#define __fortify_memcpy_chk(p, q, size, p_size, q_size,		\
			     p_size_field, q_size_field, op) ({		\
	size_t __fortify_size = (size_t)(size);				\
	fortify_memcpy_chk(__fortify_size, p_size, q_size,		\
			   p_size_field, q_size_field, #op);		\
	__underlying_##op(p, q, __fortify_size);			\
})

/*
 * __builtin_object_size() must be captured here to avoid evaluating argument
 * side-effects further into the macro layers.
 */
#define memcpy(p, q, s)  __fortify_memcpy_chk(p, q, s,			\
		__builtin_object_size(p, 0), __builtin_object_size(q, 0), \
		__builtin_object_size(p, 1), __builtin_object_size(q, 1), \
		memcpy)
#define memmove(p, q, s)  __fortify_memcpy_chk(p, q, s,			\
		__builtin_object_size(p, 0), __builtin_object_size(q, 0), \
		__builtin_object_size(p, 1), __builtin_object_size(q, 1), \
		memmove)

extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan);
extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan);
__FORTIFY_INLINE void *memscan(void *p, int c, __kernel_size_t size)
__FORTIFY_INLINE void *memscan(void * const POS0 p, int c, __kernel_size_t size)
{
{
	size_t p_size = __builtin_object_size(p, 0);
	size_t p_size = __builtin_object_size(p, 0);


@@ -253,7 +387,8 @@ __FORTIFY_INLINE void *memscan(void *p, int c, __kernel_size_t size)
	return __real_memscan(p, c, size);
	return __real_memscan(p, c, size);
}
}


__FORTIFY_INLINE int memcmp(const void *p, const void *q, __kernel_size_t size)
__FORTIFY_INLINE __diagnose_as(__builtin_memcmp, 1, 2, 3)
int memcmp(const void * const POS0 p, const void * const POS0 q, __kernel_size_t size)
{
{
	size_t p_size = __builtin_object_size(p, 0);
	size_t p_size = __builtin_object_size(p, 0);
	size_t q_size = __builtin_object_size(q, 0);
	size_t q_size = __builtin_object_size(q, 0);
@@ -269,7 +404,8 @@ __FORTIFY_INLINE int memcmp(const void *p, const void *q, __kernel_size_t size)
	return __underlying_memcmp(p, q, size);
	return __underlying_memcmp(p, q, size);
}
}


__FORTIFY_INLINE void *memchr(const void *p, int c, __kernel_size_t size)
__FORTIFY_INLINE __diagnose_as(__builtin_memchr, 1, 2, 3)
void *memchr(const void * const POS0 p, int c, __kernel_size_t size)
{
{
	size_t p_size = __builtin_object_size(p, 0);
	size_t p_size = __builtin_object_size(p, 0);


@@ -281,7 +417,7 @@ __FORTIFY_INLINE void *memchr(const void *p, int c, __kernel_size_t size)
}
}


void *__real_memchr_inv(const void *s, int c, size_t n) __RENAME(memchr_inv);
void *__real_memchr_inv(const void *s, int c, size_t n) __RENAME(memchr_inv);
__FORTIFY_INLINE void *memchr_inv(const void *p, int c, size_t size)
__FORTIFY_INLINE void *memchr_inv(const void * const POS0 p, int c, size_t size)
{
{
	size_t p_size = __builtin_object_size(p, 0);
	size_t p_size = __builtin_object_size(p, 0);


@@ -293,7 +429,7 @@ __FORTIFY_INLINE void *memchr_inv(const void *p, int c, size_t size)
}
}


extern void *__real_kmemdup(const void *src, size_t len, gfp_t gfp) __RENAME(kmemdup);
extern void *__real_kmemdup(const void *src, size_t len, gfp_t gfp) __RENAME(kmemdup);
__FORTIFY_INLINE void *kmemdup(const void *p, size_t size, gfp_t gfp)
__FORTIFY_INLINE void *kmemdup(const void * const POS0 p, size_t size, gfp_t gfp)
{
{
	size_t p_size = __builtin_object_size(p, 0);
	size_t p_size = __builtin_object_size(p, 0);


@@ -304,13 +440,15 @@ __FORTIFY_INLINE void *kmemdup(const void *p, size_t size, gfp_t gfp)
	return __real_kmemdup(p, size, gfp);
	return __real_kmemdup(p, size, gfp);
}
}


/* defined after fortified strlen and memcpy to reuse them */
/* Defined after fortified strlen to reuse it. */
__FORTIFY_INLINE char *strcpy(char *p, const char *q)
__FORTIFY_INLINE __diagnose_as(__builtin_strcpy, 1, 2)
char *strcpy(char * const POS p, const char * const POS q)
{
{
	size_t p_size = __builtin_object_size(p, 1);
	size_t p_size = __builtin_object_size(p, 1);
	size_t q_size = __builtin_object_size(q, 1);
	size_t q_size = __builtin_object_size(q, 1);
	size_t size;
	size_t size;


	/* If neither buffer size is known, immediately give up. */
	if (p_size == (size_t)-1 && q_size == (size_t)-1)
	if (p_size == (size_t)-1 && q_size == (size_t)-1)
		return __underlying_strcpy(p, q);
		return __underlying_strcpy(p, q);
	size = strlen(q) + 1;
	size = strlen(q) + 1;
@@ -320,20 +458,20 @@ __FORTIFY_INLINE char *strcpy(char *p, const char *q)
	/* Run-time check for dynamic size overflow. */
	/* Run-time check for dynamic size overflow. */
	if (p_size < size)
	if (p_size < size)
		fortify_panic(__func__);
		fortify_panic(__func__);
	memcpy(p, q, size);
	__underlying_memcpy(p, q, size);
	return p;
	return p;
}
}


/* Don't use these outside the FORITFY_SOURCE implementation */
/* Don't use these outside the FORITFY_SOURCE implementation */
#undef __underlying_memchr
#undef __underlying_memchr
#undef __underlying_memcmp
#undef __underlying_memcmp
#undef __underlying_memcpy
#undef __underlying_memmove
#undef __underlying_memset
#undef __underlying_strcat
#undef __underlying_strcat
#undef __underlying_strcpy
#undef __underlying_strcpy
#undef __underlying_strlen
#undef __underlying_strlen
#undef __underlying_strncat
#undef __underlying_strncat
#undef __underlying_strncpy
#undef __underlying_strncpy


#undef POS
#undef POS0

#endif /* _LINUX_FORTIFY_STRING_H_ */
#endif /* _LINUX_FORTIFY_STRING_H_ */
+2 −1
Original line number Original line Diff line number Diff line
@@ -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)
Loading