From 9faef705ba590f57d83883505b29649c869b3f56 Mon Sep 17 00:00:00 2001 From: Ryan Salsamendi Date: Fri, 9 Jun 2017 12:01:39 -0700 Subject: [PATCH] UPSTREAM: arch/x86: Fix undefined behavior Fixes report found by undefined behavior sanitizer. Dereferencing a pointer that is not aligned to the size of access is undefined behavior. Switch to memcpy() for unaligned write to EBDA_LOWMEM. Change other write16()s in setup_ebda() to memcpy() for consistency. BUG=none BRANCH=none TEST=none Change-Id: Ic28f2b8d8b84a71b65ceb1a47015eef99a95319a Signed-off-by: Patrick Georgi Original-Commit-Id: f0b071202377e3e4c5550ddaa28a727556745fa7 Original-Change-Id: I79814bd47a14ec59d84068b11d094dc2531995d9 Original-Signed-off-by: Ryan Salsamendi Original-Reviewed-on: https://review.coreboot.org/20132 Original-Tested-by: build bot (Jenkins) Original-Reviewed-by: Aaron Durbin Original-Reviewed-by: Philippe Mathieu-Daud Reviewed-on: https://chromium-review.googlesource.com/539202 Commit-Ready: Patrick Georgi Tested-by: Patrick Georgi Reviewed-by: Patrick Georgi --- src/arch/x86/ebda.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/arch/x86/ebda.c b/src/arch/x86/ebda.c index 284b5be1b5..b5dfb413ae 100644 --- a/src/arch/x86/ebda.c +++ b/src/arch/x86/ebda.c @@ -22,6 +22,10 @@ void setup_ebda(u32 low_memory_size, u16 ebda_segment, u16 ebda_size) { + u16 low_memory_kb; + u16 ebda_kb; + void *ebda; + /* Skip in S3 resume path */ if (acpi_is_wakeup_s3()) return; @@ -29,15 +33,20 @@ void setup_ebda(u32 low_memory_size, u16 ebda_segment, u16 ebda_size) if (!low_memory_size || !ebda_segment || !ebda_size) return; - /* clear BIOS DATA AREA */ - memset((void *)X86_BDA_BASE, 0, X86_BDA_SIZE); + low_memory_kb = low_memory_size >> 10; + ebda_kb = ebda_size >> 10; + ebda = (void *)((uintptr_t)ebda_segment << 4); - write16(X86_EBDA_LOWMEM, (low_memory_size >> 10)); - write16(X86_EBDA_SEGMENT, ebda_segment); + /* clear BIOS DATA AREA */ + memset(X86_BDA_BASE, 0, X86_BDA_SIZE); + + /* Avoid unaligned write16() since it's undefined behavior */ + memcpy(X86_EBDA_LOWMEM, &low_memory_kb, sizeof(low_memory_kb)); + memcpy(X86_EBDA_SEGMENT, &ebda_segment, sizeof(ebda_segment)); /* Set up EBDA */ - memset((void *)((uintptr_t)ebda_segment << 4), 0, ebda_size); - write16((void *)((uintptr_t)ebda_segment << 4), (ebda_size >> 10)); + memset(ebda, 0, ebda_size); + memcpy(ebda, &ebda_kb, sizeof(ebda_kb)); } void setup_default_ebda(void)