From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752766AbcD2ASZ (ORCPT ); Thu, 28 Apr 2016 20:18:25 -0400 Received: from mail-pa0-f41.google.com ([209.85.220.41]:33749 "EHLO mail-pa0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751986AbcD2ASY (ORCPT ); Thu, 28 Apr 2016 20:18:24 -0400 Date: Thu, 28 Apr 2016 17:18:22 -0700 From: Kees Cook To: Ingo Molnar Cc: Lasse Collin , One Thousand Gnomes , "H. Peter Anvin" , Thomas Gleixner , Ingo Molnar , "x86@kernel.org" , LKML , Yinghai Lu , Baoquan He , Borislav Petkov Subject: [PATCH v4] x86/boot: Warn on future overlapping memcpy() use Message-ID: <20160429001822.GA15625@www.outflux.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org If an overlapping memcpy() is ever attempted, we should at least report it, in case it might lead to problems, so it could be changed to a memmove() call instead. Suggested-by: Ingo Molnar Signed-off-by: Kees Cook --- v4: - use __memcpy not memcpy since we've already done the check. v3: - call memmove in addition to doing the warning v2: - warn about overlapping region --- arch/x86/boot/compressed/string.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/arch/x86/boot/compressed/string.c b/arch/x86/boot/compressed/string.c index 2befeca1aada..5ac3acb5699f 100644 --- a/arch/x86/boot/compressed/string.c +++ b/arch/x86/boot/compressed/string.c @@ -8,7 +8,7 @@ #include "../string.c" #ifdef CONFIG_X86_32 -void *memcpy(void *dest, const void *src, size_t n) +static void *__memcpy(void *dest, const void *src, size_t n) { int d0, d1, d2; asm volatile( @@ -22,7 +22,7 @@ void *memcpy(void *dest, const void *src, size_t n) return dest; } #else -void *memcpy(void *dest, const void *src, size_t n) +static void *__memcpy(void *dest, const void *src, size_t n) { long d0, d1, d2; asm volatile( @@ -53,10 +53,20 @@ void *memmove(void *dest, const void *src, size_t n) const unsigned char *s = src; if (d <= s || d - s >= n) - return memcpy(dest, src, n); + return __memcpy(dest, src, n); while (n-- > 0) d[n] = s[n]; return dest; } + +/* Detect and warn about potential overlaps, but handle them with memmove. */ +void *memcpy(void *dest, const void *src, size_t n) +{ + if (dest > src && dest - src < n) { + warn("Avoiding potentially unsafe overlapping memcpy()!"); + return memmove(dest, src, n); + } + return __memcpy(dest, src, n); +} -- 2.6.3 -- Kees Cook Chrome OS & Brillo Security