1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
Description: mind endianness when reading ELF objects
.
cbmc (5.12-2) unstable; urgency=low
.
* __float128 is not available on all architectures
* Fix endianness conversion in ELF reader
Author: Michael Tautschnig <mt@debian.org>
---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:
Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: 2020-04-29
--- cbmc-5.12.orig/src/goto-programs/elf_reader.cpp
+++ cbmc-5.12/src/goto-programs/elf_reader.cpp
@@ -14,6 +14,37 @@ Author:
#include <istream>
+static void u16_to_native_endian_inplace(bool le_input, uint16_t &input)
+{
+ const uint8_t *input_as_bytes = reinterpret_cast<uint8_t *>(&input);
+ input = (((uint16_t)input_as_bytes[0]) << (le_input ? 0 : 8)) |
+ (((uint16_t)input_as_bytes[1]) << (le_input ? 8 : 0));
+}
+
+static void u32_to_native_endian_inplace(bool le_input, uint32_t &input)
+{
+ const uint8_t *input_as_bytes = reinterpret_cast<uint8_t *>(&input);
+ input = (((uint32_t)input_as_bytes[0]) << (le_input ? 0 : 24)) |
+ (((uint32_t)input_as_bytes[1]) << (le_input ? 8 : 16)) |
+ (((uint32_t)input_as_bytes[2]) << (le_input ? 16 : 8)) |
+ (((uint32_t)input_as_bytes[3]) << (le_input ? 24 : 0));
+}
+
+static void u64_to_native_endian_inplace(bool le_input, unsigned long long &input)
+{
+ static_assert(sizeof(unsigned long long) == 8, "unsigned long long expected to be 8 bytes");
+ const uint8_t *input_as_bytes = reinterpret_cast<uint8_t *>(&input);
+ input = (((unsigned long long)input_as_bytes[0]) << (le_input ? 0 : 56)) |
+ (((unsigned long long)input_as_bytes[1]) << (le_input ? 8 : 48)) |
+ (((unsigned long long)input_as_bytes[2]) << (le_input ? 16 : 40)) |
+ (((unsigned long long)input_as_bytes[3]) << (le_input ? 24 : 32)) |
+ (((unsigned long long)input_as_bytes[4]) << (le_input ? 32 : 24)) |
+ (((unsigned long long)input_as_bytes[5]) << (le_input ? 40 : 16)) |
+ (((unsigned long long)input_as_bytes[6]) << (le_input ? 48 : 8)) |
+ (((unsigned long long)input_as_bytes[7]) << (le_input ? 56 : 0));
+}
+
+
elf_readert::elf_readert(std::istream &_in):in(_in)
{
// read 32-bit header
@@ -43,6 +74,20 @@ elf_readert::elf_readert(std::istream &_
else
throw deserialization_exceptiont("ELF32 header malformed (EI_DATA)");
+ u16_to_native_endian_inplace(little_endian, elf32_header.e_type);
+ u16_to_native_endian_inplace(little_endian, elf32_header.e_machine);
+ u32_to_native_endian_inplace(little_endian, elf32_header.e_version);
+ u32_to_native_endian_inplace(little_endian, elf32_header.e_entry);
+ u32_to_native_endian_inplace(little_endian, elf32_header.e_phoff);
+ u32_to_native_endian_inplace(little_endian, elf32_header.e_shoff);
+ u32_to_native_endian_inplace(little_endian, elf32_header.e_flags);
+ u16_to_native_endian_inplace(little_endian, elf32_header.e_ehsize);
+ u16_to_native_endian_inplace(little_endian, elf32_header.e_phentsize);
+ u16_to_native_endian_inplace(little_endian, elf32_header.e_phnum);
+ u16_to_native_endian_inplace(little_endian, elf32_header.e_shentsize);
+ u16_to_native_endian_inplace(little_endian, elf32_header.e_shnum);
+ u16_to_native_endian_inplace(little_endian, elf32_header.e_shstrndx);
+
if(elf32_header.e_version!=1)
throw deserialization_exceptiont("unknown ELF32 version");
@@ -64,6 +109,16 @@ elf_readert::elf_readert(std::istream &_
in.read(
reinterpret_cast<char*>(&elf32_section_header_table[i]),
sizeof(Elf32_Shdr));
+ u32_to_native_endian_inplace(little_endian, elf32_section_header_table[i].sh_name);
+ u32_to_native_endian_inplace(little_endian, elf32_section_header_table[i].sh_type);
+ u32_to_native_endian_inplace(little_endian, elf32_section_header_table[i].sh_flags);
+ u32_to_native_endian_inplace(little_endian, elf32_section_header_table[i].sh_addr);
+ u32_to_native_endian_inplace(little_endian, elf32_section_header_table[i].sh_offset);
+ u32_to_native_endian_inplace(little_endian, elf32_section_header_table[i].sh_size);
+ u32_to_native_endian_inplace(little_endian, elf32_section_header_table[i].sh_link);
+ u32_to_native_endian_inplace(little_endian, elf32_section_header_table[i].sh_info);
+ u32_to_native_endian_inplace(little_endian, elf32_section_header_table[i].sh_addralign);
+ u32_to_native_endian_inplace(little_endian, elf32_section_header_table[i].sh_entsize);
}
// string table
@@ -89,6 +144,19 @@ elf_readert::elf_readert(std::istream &_
little_endian=false;
else
throw deserialization_exceptiont("ELF64 header malformed (EI_DATA)");
+ u16_to_native_endian_inplace(little_endian, elf64_header.e_type);
+ u16_to_native_endian_inplace(little_endian, elf64_header.e_machine);
+ u32_to_native_endian_inplace(little_endian, elf64_header.e_version);
+ u64_to_native_endian_inplace(little_endian, elf64_header.e_entry);
+ u64_to_native_endian_inplace(little_endian, elf64_header.e_phoff);
+ u64_to_native_endian_inplace(little_endian, elf64_header.e_shoff);
+ u32_to_native_endian_inplace(little_endian, elf64_header.e_flags);
+ u16_to_native_endian_inplace(little_endian, elf64_header.e_ehsize);
+ u16_to_native_endian_inplace(little_endian, elf64_header.e_phentsize);
+ u16_to_native_endian_inplace(little_endian, elf64_header.e_phnum);
+ u16_to_native_endian_inplace(little_endian, elf64_header.e_shentsize);
+ u16_to_native_endian_inplace(little_endian, elf64_header.e_shnum);
+ u16_to_native_endian_inplace(little_endian, elf64_header.e_shstrndx);
if(elf64_header.e_version!=1)
throw deserialization_exceptiont("unknown ELF64 version");
@@ -111,6 +179,16 @@ elf_readert::elf_readert(std::istream &_
in.read(
reinterpret_cast<char*>(&elf64_section_header_table[i]),
sizeof(Elf64_Shdr));
+ u32_to_native_endian_inplace(little_endian, elf64_section_header_table[i].sh_name);
+ u32_to_native_endian_inplace(little_endian, elf64_section_header_table[i].sh_type);
+ u64_to_native_endian_inplace(little_endian, elf64_section_header_table[i].sh_flags);
+ u64_to_native_endian_inplace(little_endian, elf64_section_header_table[i].sh_addr);
+ u64_to_native_endian_inplace(little_endian, elf64_section_header_table[i].sh_offset);
+ u64_to_native_endian_inplace(little_endian, elf64_section_header_table[i].sh_size);
+ u32_to_native_endian_inplace(little_endian, elf64_section_header_table[i].sh_link);
+ u32_to_native_endian_inplace(little_endian, elf64_section_header_table[i].sh_info);
+ u64_to_native_endian_inplace(little_endian, elf64_section_header_table[i].sh_addralign);
+ u64_to_native_endian_inplace(little_endian, elf64_section_header_table[i].sh_entsize);
}
// string table
|