|
21 | 21 | #include <linux/slab.h>
|
22 | 22 | #include <linux/types.h>
|
23 | 23 |
|
24 |
| -#define elf_addr_to_cpu elf64_to_cpu |
25 |
| - |
26 | 24 | static inline bool elf_is_elf_file(const struct elfhdr *ehdr)
|
27 | 25 | {
|
28 | 26 | return memcmp(ehdr->e_ident, ELFMAG, SELFMAG) == 0;
|
@@ -152,16 +150,31 @@ static int elf_read_ehdr(const char *buf, size_t len, struct elfhdr *ehdr)
|
152 | 150 | ehdr->e_type = elf16_to_cpu(ehdr, buf_ehdr->e_type);
|
153 | 151 | ehdr->e_machine = elf16_to_cpu(ehdr, buf_ehdr->e_machine);
|
154 | 152 | ehdr->e_version = elf32_to_cpu(ehdr, buf_ehdr->e_version);
|
155 |
| - ehdr->e_entry = elf_addr_to_cpu(ehdr, buf_ehdr->e_entry); |
156 |
| - ehdr->e_phoff = elf_addr_to_cpu(ehdr, buf_ehdr->e_phoff); |
157 |
| - ehdr->e_shoff = elf_addr_to_cpu(ehdr, buf_ehdr->e_shoff); |
158 | 153 | ehdr->e_flags = elf32_to_cpu(ehdr, buf_ehdr->e_flags);
|
159 | 154 | ehdr->e_phentsize = elf16_to_cpu(ehdr, buf_ehdr->e_phentsize);
|
160 | 155 | ehdr->e_phnum = elf16_to_cpu(ehdr, buf_ehdr->e_phnum);
|
161 | 156 | ehdr->e_shentsize = elf16_to_cpu(ehdr, buf_ehdr->e_shentsize);
|
162 | 157 | ehdr->e_shnum = elf16_to_cpu(ehdr, buf_ehdr->e_shnum);
|
163 | 158 | ehdr->e_shstrndx = elf16_to_cpu(ehdr, buf_ehdr->e_shstrndx);
|
164 | 159 |
|
| 160 | + switch (ehdr->e_ident[EI_CLASS]) { |
| 161 | + case ELFCLASS64: |
| 162 | + ehdr->e_entry = elf64_to_cpu(ehdr, buf_ehdr->e_entry); |
| 163 | + ehdr->e_phoff = elf64_to_cpu(ehdr, buf_ehdr->e_phoff); |
| 164 | + ehdr->e_shoff = elf64_to_cpu(ehdr, buf_ehdr->e_shoff); |
| 165 | + break; |
| 166 | + |
| 167 | + case ELFCLASS32: |
| 168 | + ehdr->e_entry = elf32_to_cpu(ehdr, buf_ehdr->e_entry); |
| 169 | + ehdr->e_phoff = elf32_to_cpu(ehdr, buf_ehdr->e_phoff); |
| 170 | + ehdr->e_shoff = elf32_to_cpu(ehdr, buf_ehdr->e_shoff); |
| 171 | + break; |
| 172 | + |
| 173 | + default: |
| 174 | + pr_debug("Unknown ELF class.\n"); |
| 175 | + return -EINVAL; |
| 176 | + } |
| 177 | + |
165 | 178 | return elf_is_ehdr_sane(ehdr, len) ? 0 : -ENOEXEC;
|
166 | 179 | }
|
167 | 180 |
|
@@ -192,25 +205,39 @@ static int elf_read_phdr(const char *buf, size_t len,
|
192 | 205 | {
|
193 | 206 | /* Override the const in proghdrs, we are the ones doing the loading. */
|
194 | 207 | struct elf_phdr *phdr = (struct elf_phdr *) &elf_info->proghdrs[idx];
|
| 208 | + const struct elfhdr *ehdr = elf_info->ehdr; |
195 | 209 | const char *pbuf;
|
196 | 210 | struct elf_phdr *buf_phdr;
|
197 | 211 |
|
198 | 212 | pbuf = buf + elf_info->ehdr->e_phoff + (idx * sizeof(*buf_phdr));
|
199 | 213 | buf_phdr = (struct elf_phdr *) pbuf;
|
200 | 214 |
|
201 | 215 | phdr->p_type = elf32_to_cpu(elf_info->ehdr, buf_phdr->p_type);
|
202 |
| - phdr->p_offset = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_offset); |
203 |
| - phdr->p_paddr = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_paddr); |
204 |
| - phdr->p_vaddr = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_vaddr); |
205 | 216 | phdr->p_flags = elf32_to_cpu(elf_info->ehdr, buf_phdr->p_flags);
|
206 | 217 |
|
207 |
| - /* |
208 |
| - * The following fields have a type equivalent to Elf_Addr |
209 |
| - * both in 32 bit and 64 bit ELF. |
210 |
| - */ |
211 |
| - phdr->p_filesz = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_filesz); |
212 |
| - phdr->p_memsz = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_memsz); |
213 |
| - phdr->p_align = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_align); |
| 218 | + switch (ehdr->e_ident[EI_CLASS]) { |
| 219 | + case ELFCLASS64: |
| 220 | + phdr->p_offset = elf64_to_cpu(ehdr, buf_phdr->p_offset); |
| 221 | + phdr->p_paddr = elf64_to_cpu(ehdr, buf_phdr->p_paddr); |
| 222 | + phdr->p_vaddr = elf64_to_cpu(ehdr, buf_phdr->p_vaddr); |
| 223 | + phdr->p_filesz = elf64_to_cpu(ehdr, buf_phdr->p_filesz); |
| 224 | + phdr->p_memsz = elf64_to_cpu(ehdr, buf_phdr->p_memsz); |
| 225 | + phdr->p_align = elf64_to_cpu(ehdr, buf_phdr->p_align); |
| 226 | + break; |
| 227 | + |
| 228 | + case ELFCLASS32: |
| 229 | + phdr->p_offset = elf32_to_cpu(ehdr, buf_phdr->p_offset); |
| 230 | + phdr->p_paddr = elf32_to_cpu(ehdr, buf_phdr->p_paddr); |
| 231 | + phdr->p_vaddr = elf32_to_cpu(ehdr, buf_phdr->p_vaddr); |
| 232 | + phdr->p_filesz = elf32_to_cpu(ehdr, buf_phdr->p_filesz); |
| 233 | + phdr->p_memsz = elf32_to_cpu(ehdr, buf_phdr->p_memsz); |
| 234 | + phdr->p_align = elf32_to_cpu(ehdr, buf_phdr->p_align); |
| 235 | + break; |
| 236 | + |
| 237 | + default: |
| 238 | + pr_debug("Unknown ELF class.\n"); |
| 239 | + return -EINVAL; |
| 240 | + } |
214 | 241 |
|
215 | 242 | return elf_is_phdr_sane(phdr, len) ? 0 : -ENOEXEC;
|
216 | 243 | }
|
|
0 commit comments