summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorCyril Bur <cyril.bur@au1.ibm.com>2017-08-03 16:45:44 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-08-15 16:37:14 +1000
commitb24ad955af7512b3f771640d313125b61af602aa (patch)
treec755630488bb0f5702c7449616689b039ec1e33d /core
parent00d05bc8a20abfdc2d692cccb250844f1477e95a (diff)
downloadblackbird-skiboot-b24ad955af7512b3f771640d313125b61af602aa.tar.gz
blackbird-skiboot-b24ad955af7512b3f771640d313125b61af602aa.zip
core/flash core/init: Fix unintended sign extension
According to Coverity: le16_to_cpu(elf64->e_shnum) is promoted in `le16_to_cpu(elf64->e_shentsize) * le16_to_cpu(elf64->e_shnum)` to type int (32 bits, signed), then sign-extended to type unsigned long long (64 bits, unsigned). If `le16_to_cpu(elf64->e_shentsize) * le16_to_cpu(elf64->e_shnum)` is greater than 0x7FFFFFFF, the upper bits of the result will all be 1. I'm sure in practice this can't happen since this would require either/or e_shnum and e_shentsize to be quite large. Fixes: CID 138019, 137707, 137706, 137708 Signed-off-by: Cyril Bur <cyril.bur@au1.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core')
-rw-r--r--core/flash.c4
-rw-r--r--core/init.c6
2 files changed, 6 insertions, 4 deletions
diff --git a/core/flash.c b/core/flash.c
index 8a908e5b..53e6eba0 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -438,8 +438,8 @@ static size_t sizeof_elf_from_hdr(void *buf)
if (elf->ei_class == ELF_CLASS_64) {
struct elf64_hdr *elf64 = (struct elf64_hdr*) buf;
sz = le64_to_cpu(elf64->e_shoff) +
- (le16_to_cpu(elf64->e_shentsize) *
- le16_to_cpu(elf64->e_shnum));
+ ((uint32_t)le16_to_cpu(elf64->e_shentsize) *
+ (uint32_t)le16_to_cpu(elf64->e_shnum));
} else if (elf->ei_class == ELF_CLASS_32) {
struct elf32_hdr *elf32 = (struct elf32_hdr*) buf;
sz = le32_to_cpu(elf32->e_shoff) +
diff --git a/core/init.c b/core/init.c
index 61b531c7..a96a69c8 100644
--- a/core/init.c
+++ b/core/init.c
@@ -119,7 +119,8 @@ static bool try_load_elf64_le(struct elf_hdr *header)
kernel_32bit = false;
kernel_size = le64_to_cpu(kh->e_shoff) +
- (le16_to_cpu(kh->e_shentsize) * le16_to_cpu(kh->e_shnum));
+ ((uint32_t)le16_to_cpu(kh->e_shentsize) *
+ (uint32_t)le16_to_cpu(kh->e_shnum));
prlog(PR_DEBUG, "INIT: 64-bit kernel entry at 0x%llx, size 0x%lx\n",
kernel_entry, kernel_size);
@@ -196,7 +197,8 @@ static bool try_load_elf64(struct elf_hdr *header)
kernel_entry += load_base;
kernel_32bit = false;
- kernel_size = kh->e_shoff + (kh->e_shentsize * kh->e_shnum);
+ kernel_size = kh->e_shoff +
+ ((uint32_t)kh->e_shentsize * (uint32_t)kh->e_shnum);
printf("INIT: 64-bit kernel entry at 0x%llx, size 0x%lx\n",
kernel_entry, kernel_size);
OpenPOWER on IntegriCloud