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: Kees Cook <keescook@chromium.org>
This commit is contained in:
Kees Cook 2021-06-16 14:48:19 -07:00
parent f68f2ff915
commit 938a000e3f
5 changed files with 17 additions and 18 deletions

View File

@ -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

View File

@ -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)
{ {

View File

@ -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, 0), __builtin_object_size(q, 0), \
__builtin_object_size(p, 1), __builtin_object_size(q, 1), \ __builtin_object_size(p, 1), __builtin_object_size(q, 1), \
memcpy) memcpy)
#define memmove(p, q, s) __fortify_memcpy_chk(p, q, s, \
__FORTIFY_INLINE void *memmove(void *p, const void *q, __kernel_size_t size) __builtin_object_size(p, 0), __builtin_object_size(q, 0), \
{ __builtin_object_size(p, 1), __builtin_object_size(q, 1), \
size_t p_size = __builtin_object_size(p, 0); memmove)
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);
}
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 *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 */ /* Don't use these outside the FORITFY_SOURCE implementation */
#undef __underlying_memchr #undef __underlying_memchr
#undef __underlying_memcmp #undef __underlying_memcmp
#undef __underlying_memmove
#undef __underlying_memset #undef __underlying_memset
#undef __underlying_strcat #undef __underlying_strcat
#undef __underlying_strcpy #undef __underlying_strcpy

View File

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

View File

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