Commit 938a000e authored by Kees Cook's avatar Kees Cook
Browse files

fortify: Detect struct member overflows in memmove() at compile-time



As done for memcpy(), also update memmove() to use the same tightened
compile-time checks under CONFIG_FORTIFY_SOURCE.

Signed-off-by: default avatarKees Cook <keescook@chromium.org>
parent f68f2ff9
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -37,10 +37,11 @@
 * try to define their own functions if these are not defined as macros.
 */
#define memzero(s, n)	memset((s), 0, (n))
#ifndef memmove
#define memmove		memmove

/* Functions used by the included decompressor code below. */
void *memmove(void *dest, const void *src, size_t n);
#endif

/*
 * This is set up by the setup-routine at boot-time
+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@

#undef memcpy
#undef memset
#undef memmove

__visible void *memcpy(void *to, const void *from, size_t n)
{
+4 −17
Original line number Diff line number Diff line
@@ -309,22 +309,10 @@ __FORTIFY_INLINE void fortify_memcpy_chk(__kernel_size_t size,
		__builtin_object_size(p, 0), __builtin_object_size(q, 0), \
		__builtin_object_size(p, 1), __builtin_object_size(q, 1), \
		memcpy)

__FORTIFY_INLINE void *memmove(void *p, const void *q, __kernel_size_t size)
{
	size_t p_size = __builtin_object_size(p, 0);
	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__);
	return __underlying_memmove(p, q, size);
}
#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);
__FORTIFY_INLINE void *memscan(void *p, int c, __kernel_size_t size)
@@ -413,7 +401,6 @@ __FORTIFY_INLINE char *strcpy(char *p, const char *q)
/* Don't use these outside the FORITFY_SOURCE implementation */
#undef __underlying_memchr
#undef __underlying_memcmp
#undef __underlying_memmove
#undef __underlying_memset
#undef __underlying_strcat
#undef __underlying_strcpy
+5 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
#define TEST	\
	memmove(large, instance.buf, sizeof(instance.buf) + 1)

#include "test_fortify.h"
+5 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
#define TEST	\
	memmove(instance.buf, large, sizeof(instance.buf) + 1)

#include "test_fortify.h"