aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2021-06-16 14:48:19 -0700
committerKees Cook <keescook@chromium.org>2021-06-19 00:25:30 -0700
commitb44eff85708d836f39515789c036c5003dc34ec6 (patch)
tree403675b2694785bf22bad643e68024d655a0b248
parent21405e341f4b8742f8c6d8b91ad39348d7cf970f (diff)
downloadlinux-b44eff85708d836f39515789c036c5003dc34ec6.tar.gz
fortify: Detect struct member overflows in memmove()
As done for memcpy(), also update memmove() to use the same tightened checks under CONFIG_FORTIFY_SOURCE. Signed-off-by: Kees Cook <keescook@chromium.org>
-rw-r--r--arch/x86/boot/compressed/misc.c3
-rw-r--r--arch/x86/lib/memcpy_32.c1
-rw-r--r--include/linux/fortify-string.h16
-rw-r--r--lib/test_fortify/read_overflow2_field-memmove.c (renamed from lib/test_fortify/read_overflow2-memmove.c)2
-rw-r--r--lib/test_fortify/write_overflow_field-memmove.c (renamed from lib/test_fortify/write_overflow-memmove.c)2
5 files changed, 9 insertions, 15 deletions
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 743f13ea25c12..83ff4354970e5 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -34,10 +34,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
diff --git a/arch/x86/lib/memcpy_32.c b/arch/x86/lib/memcpy_32.c
index e565d1c9019ee..f19b7fd07f042 100644
--- a/arch/x86/lib/memcpy_32.c
+++ b/arch/x86/lib/memcpy_32.c
@@ -4,6 +4,7 @@
#undef memcpy
#undef memset
+#undef memmove
__visible void *memcpy(void *to, const void *from, size_t n)
{
diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h
index 950d38657b31a..3a96d386b0d4d 100644
--- a/include/linux/fortify-string.h
+++ b/include/linux/fortify-string.h
@@ -278,19 +278,11 @@ __FORTIFY_INLINE void *__fortify_memcpy(void *p, const void *q,
return __underlying_memcpy(p, q, size);
}
-__FORTIFY_INLINE void *memmove(void *p, const void *q, __kernel_size_t size)
+#define memmove(p, q, s) __fortify_memmove(p, q, s)
+__FORTIFY_INLINE void *__fortify_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__);
+ __fortify_memcpy_chk(p, q, size, "memmove");
return __underlying_memmove(p, q, size);
}
diff --git a/lib/test_fortify/read_overflow2-memmove.c b/lib/test_fortify/read_overflow2_field-memmove.c
index bc905f9278990..6cc2724c8f62c 100644
--- a/lib/test_fortify/read_overflow2-memmove.c
+++ b/lib/test_fortify/read_overflow2_field-memmove.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
#define TEST \
- memmove(large, small, sizeof(large))
+ memmove(large, instance.buf, sizeof(instance.buf) + 1)
#include "test_fortify.h"
diff --git a/lib/test_fortify/write_overflow-memmove.c b/lib/test_fortify/write_overflow_field-memmove.c
index 6cbd2af678567..377fcf9bb2fdc 100644
--- a/lib/test_fortify/write_overflow-memmove.c
+++ b/lib/test_fortify/write_overflow_field-memmove.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
#define TEST \
- memmove(small, large, sizeof(large))
+ memmove(instance.buf, large, sizeof(instance.buf) + 1)
#include "test_fortify.h"