[coreboot-gerrit] Change in coreboot[master]: libpayload: Support unaligned pointer for memcpy, memmove an...

Jérémy Compostella (Code Review) gerrit at coreboot.org
Tue Jul 11 23:06:49 CEST 2017


Jérémy Compostella has uploaded this change for review. ( https://review.coreboot.org/20535


Change subject: libpayload: Support unaligned pointer for memcpy, memmove and memcmp
......................................................................

libpayload: Support unaligned pointer for memcpy, memmove and memcmp

The memcpy(), memmove() and memcmp() functions use word by word
operations regardless of the pointer alignment.  Depending on the
platform, this could lead to a crash.

This patch makes the memcpy(), memmove() or memcmp() operate byte per
byte if they are supplied with unaligned pointers.

Change-Id: I0b668739b7b58d47266f10f2dff2dc9cbf38577e
Signed-off-by: Jeremy Compostella <jeremy.compostella at intel.com>
---
M payloads/libpayload/libc/memory.c
1 file changed, 20 insertions(+), 2 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/35/20535/1

diff --git a/payloads/libpayload/libc/memory.c b/payloads/libpayload/libc/memory.c
index 1adfb32..78418ba 100644
--- a/payloads/libpayload/libc/memory.c
+++ b/payloads/libpayload/libc/memory.c
@@ -66,13 +66,19 @@
 	size_t i;
 	void *ret = dst;
 
+	if (!IS_ALIGNED((uintptr_t)dst, sizeof(unsigned long)) ||
+	    !IS_ALIGNED((uintptr_t)src, sizeof(unsigned long)))
+		goto copy_bytes;
+
 	for(i = 0; i < n / sizeof(unsigned long); i++)
 		((unsigned long *)dst)[i] = ((unsigned long *)src)[i];
 
 	src += i * sizeof(unsigned long);
 	dst += i * sizeof(unsigned long);
+	n -= i * sizeof(unsigned long);
 
-	for(i = 0; i < n % sizeof(unsigned long); i++)
+copy_bytes:
+	for(i = 0; i < n ; i++)
 		((u8 *)dst)[i] = ((u8 *)src)[i];
 
 	return ret;
@@ -88,6 +94,13 @@
 
 	if (src > dst)
 		return memcpy(dst, src, n);
+
+	if (!IS_ALIGNED((uintptr_t)dst, sizeof(unsigned long)) ||
+	    !IS_ALIGNED((uintptr_t)src, sizeof(unsigned long))) {
+		for (i = n - 1; i >= 0; i--)
+			((u8 *)dst)[i] = ((u8 *)src)[i];
+		return dst;
+	}
 
 	offs = n - (n % sizeof(unsigned long));
 
@@ -116,12 +129,17 @@
 
 static int default_memcmp(const void *s1, const void *s2, size_t n)
 {
-	size_t i;
+	size_t i = 0;
+
+	if (!IS_ALIGNED((uintptr_t)s1, sizeof(unsigned long)) ||
+	    !IS_ALIGNED((uintptr_t)s2, sizeof(unsigned long)))
+		goto compare_bytes;
 
 	for (i = 0; i < n / sizeof(unsigned long); i++)
 		if (((unsigned long *)s1)[i] != ((unsigned long *)s2)[i])
 			break;	/* fall through to find differing byte */
 
+compare_bytes:
 	for (i *= sizeof(unsigned long); i < n; i++)
 		if (((u8 *)s1)[i] != ((u8 *)s2)[i])
 			return ((u8 *)s1)[i] - ((u8 *)s2)[i];

-- 
To view, visit https://review.coreboot.org/20535
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0b668739b7b58d47266f10f2dff2dc9cbf38577e
Gerrit-Change-Number: 20535
Gerrit-PatchSet: 1
Gerrit-Owner: Jérémy Compostella <jeremy.compostella at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20170711/6508eaf1/attachment.html>


More information about the coreboot-gerrit mailing list