1 /* Reconstruct an ELF file by reading the segments out of remote memory.
2 Copyright (C) 2005-2011, 2014, 2015 Red Hat, Inc.
3 This file is part of elfutils.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
7
8 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
11
12 or
13
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
17
18 or both in parallel, as here.
19
20 elfutils is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
28
29 #include <config.h>
30 #include "libelfP.h"
31
32 #include "libdwflP.h"
33
34 #include <gelf.h>
35 #include <sys/types.h>
36 #include <stdbool.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 /* Reconstruct an ELF file by reading the segments out of remote memory
41 based on the ELF file header at EHDR_VMA and the ELF program headers it
42 points to. If not null, *LOADBASEP is filled in with the difference
43 between the addresses from which the segments were read, and the
44 addresses the file headers put them at.
45
46 The function READ_MEMORY is called to copy at least MINREAD and at most
47 MAXREAD bytes from the remote memory at target address ADDRESS into the
48 local buffer at DATA; it should return -1 for errors (with code in
49 `errno'), 0 if it failed to read at least MINREAD bytes due to EOF, or
50 the number of bytes read if >= MINREAD. ARG is passed through.
51
52 PAGESIZE is the minimum page size and alignment used for the PT_LOAD
53 segments. */
54
55 Elf *
elf_from_remote_memory(GElf_Addr ehdr_vma,GElf_Xword pagesize,GElf_Addr * loadbasep,ssize_t (* read_memory)(void * arg,void * data,GElf_Addr address,size_t minread,size_t maxread),void * arg)56 elf_from_remote_memory (GElf_Addr ehdr_vma,
57 GElf_Xword pagesize,
58 GElf_Addr *loadbasep,
59 ssize_t (*read_memory) (void *arg, void *data,
60 GElf_Addr address,
61 size_t minread,
62 size_t maxread),
63 void *arg)
64 {
65 /* We might have to reserve some memory for the phdrs. Set to NULL
66 here so we can always safely free it. */
67 void *phdrsp = NULL;
68
69 /* First read in the file header and check its sanity. */
70
71 const size_t initial_bufsize = 256;
72 unsigned char *buffer = malloc (initial_bufsize);
73 if (unlikely (buffer == NULL))
74 {
75 no_memory:
76 __libdwfl_seterrno (DWFL_E_NOMEM);
77 return NULL;
78 }
79
80 ssize_t nread = (*read_memory) (arg, buffer, ehdr_vma,
81 sizeof (Elf32_Ehdr), initial_bufsize);
82 if (nread <= 0)
83 {
84 read_error:
85 free (buffer);
86 free (phdrsp);
87 __libdwfl_seterrno (nread < 0 ? DWFL_E_ERRNO : DWFL_E_TRUNCATED);
88 return NULL;
89 }
90
91 if (memcmp (buffer, ELFMAG, SELFMAG) != 0)
92 {
93 bad_elf:
94 free (buffer);
95 free (phdrsp);
96 __libdwfl_seterrno (DWFL_E_BADELF);
97 return NULL;
98 }
99
100 /* Extract the information we need from the file header. */
101
102 union
103 {
104 Elf32_Ehdr e32;
105 Elf64_Ehdr e64;
106 } ehdr;
107 Elf_Data xlatefrom =
108 {
109 .d_type = ELF_T_EHDR,
110 .d_buf = buffer,
111 .d_version = EV_CURRENT,
112 };
113 Elf_Data xlateto =
114 {
115 .d_type = ELF_T_EHDR,
116 .d_buf = &ehdr,
117 .d_size = sizeof ehdr,
118 .d_version = EV_CURRENT,
119 };
120
121 GElf_Off phoff;
122 uint_fast16_t phnum;
123 uint_fast16_t phentsize;
124 GElf_Off shdrs_end;
125
126 switch (buffer[EI_CLASS])
127 {
128 case ELFCLASS32:
129 xlatefrom.d_size = sizeof (Elf32_Ehdr);
130 if (elf32_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL)
131 {
132 libelf_error:
133 __libdwfl_seterrno (DWFL_E_LIBELF);
134 return NULL;
135 }
136 phoff = ehdr.e32.e_phoff;
137 phnum = ehdr.e32.e_phnum;
138 phentsize = ehdr.e32.e_phentsize;
139 if (phentsize != sizeof (Elf32_Phdr) || phnum == 0)
140 goto bad_elf;
141 /* NOTE if the number of sections is > 0xff00 then e_shnum
142 is zero and the actual number would come from the section
143 zero sh_size field. We ignore this here because getting shdrs
144 is just a nice bonus (see below where we trim the last phdrs
145 PT_LOAD segment). */
146 shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize;
147 break;
148
149 case ELFCLASS64:
150 xlatefrom.d_size = sizeof (Elf64_Ehdr);
151 if (elf64_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL)
152 goto libelf_error;
153 phoff = ehdr.e64.e_phoff;
154 phnum = ehdr.e64.e_phnum;
155 phentsize = ehdr.e64.e_phentsize;
156 if (phentsize != sizeof (Elf64_Phdr) || phnum == 0)
157 goto bad_elf;
158 /* See the NOTE above for shdrs_end and ehdr.e32.e_shnum. */
159 shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize;
160 break;
161
162 default:
163 goto bad_elf;
164 }
165
166
167 /* The file header tells where to find the program headers.
168 These are what we use to actually choose what to read. */
169
170 xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR;
171 xlatefrom.d_size = phnum * phentsize;
172
173 if ((size_t) nread >= phoff + phnum * phentsize)
174 /* We already have all the phdrs from the initial read. */
175 xlatefrom.d_buf = buffer + phoff;
176 else
177 {
178 /* Read in the program headers. */
179
180 if (initial_bufsize < (size_t)phnum * phentsize)
181 {
182 unsigned char *newbuf = realloc (buffer, phnum * phentsize);
183 if (newbuf == NULL)
184 {
185 free (buffer);
186 free (phdrsp);
187 goto no_memory;
188 }
189 buffer = newbuf;
190 }
191 nread = (*read_memory) (arg, buffer, ehdr_vma + phoff,
192 phnum * phentsize, phnum * phentsize);
193 if (nread <= 0)
194 goto read_error;
195
196 xlatefrom.d_buf = buffer;
197 }
198
199 bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
200 size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
201 if (unlikely (phnum > SIZE_MAX / phdr_size))
202 {
203 free (buffer);
204 goto no_memory;
205 }
206 const size_t phdrsp_bytes = phnum * phdr_size;
207 phdrsp = malloc (phdrsp_bytes);
208 if (unlikely (phdrsp == NULL))
209 {
210 free (buffer);
211 goto no_memory;
212 }
213
214 xlateto.d_buf = phdrsp;
215 xlateto.d_size = phdrsp_bytes;
216
217 /* Scan for PT_LOAD segments to find the total size of the file image. */
218 size_t contents_size = 0;
219 GElf_Off segments_end = 0;
220 GElf_Off segments_end_mem = 0;
221 GElf_Addr loadbase = ehdr_vma;
222 bool found_base = false;
223 Elf32_Phdr (*p32)[phnum] = phdrsp;
224 Elf64_Phdr (*p64)[phnum] = phdrsp;
225
226 if (class32)
227 {
228 if (! elf32_xlatetom (&xlateto, &xlatefrom, ehdr.e32.e_ident[EI_DATA]))
229 goto libelf_error;
230 }
231 else
232 {
233 if (! elf64_xlatetom (&xlateto, &xlatefrom, ehdr.e64.e_ident[EI_DATA]))
234 goto libelf_error;
235 }
236
237 for (uint_fast16_t i = 0; i < phnum; ++i)
238 {
239 GElf_Word type = class32 ? (*p32)[i].p_type : (*p64)[i].p_type;
240
241 if (type != PT_LOAD)
242 continue;
243
244 GElf_Addr vaddr = class32 ? (*p32)[i].p_vaddr : (*p64)[i].p_vaddr;
245 GElf_Xword memsz = class32 ? (*p32)[i].p_memsz : (*p64)[i].p_memsz;
246 GElf_Off offset = class32 ? (*p32)[i].p_offset : (*p64)[i].p_offset;
247 GElf_Xword filesz = class32 ? (*p32)[i].p_filesz : (*p64)[i].p_filesz;
248
249 /* Sanity check the segment load aligns with the pagesize. */
250 if (((vaddr - offset) & (pagesize - 1)) != 0)
251 goto bad_elf;
252
253 GElf_Off segment_end = ((offset + filesz + pagesize - 1)
254 & -pagesize);
255
256 if (segment_end > (GElf_Off) contents_size)
257 contents_size = segment_end;
258
259 if (!found_base && (offset & -pagesize) == 0)
260 {
261 loadbase = ehdr_vma - (vaddr & -pagesize);
262 found_base = true;
263 }
264
265 segments_end = offset + filesz;
266 segments_end_mem = offset + memsz;
267 }
268
269 /* Trim the last segment so we don't bother with zeros in the last page
270 that are off the end of the file. However, if the extra bit in that
271 page includes the section headers and the memory isn't extended (which
272 might indicate it will have been reused otherwise), keep them. */
273 if ((GElf_Off) contents_size > segments_end
274 && (GElf_Off) contents_size >= shdrs_end
275 && segments_end == segments_end_mem)
276 {
277 contents_size = segments_end;
278 if ((GElf_Off) contents_size < shdrs_end)
279 contents_size = shdrs_end;
280 }
281 else
282 contents_size = segments_end;
283
284 free (buffer);
285
286 /* Now we know the size of the whole image we want read in. */
287 buffer = calloc (1, contents_size);
288 if (buffer == NULL)
289 {
290 free (phdrsp);
291 goto no_memory;
292 }
293
294 for (uint_fast16_t i = 0; i < phnum; ++i)
295 {
296 GElf_Word type = class32 ? (*p32)[i].p_type : (*p64)[i].p_type;
297
298 if (type != PT_LOAD)
299 continue;
300
301 GElf_Addr vaddr = class32 ? (*p32)[i].p_vaddr : (*p64)[i].p_vaddr;
302 GElf_Off offset = class32 ? (*p32)[i].p_offset : (*p64)[i].p_offset;
303 GElf_Xword filesz = class32 ? (*p32)[i].p_filesz : (*p64)[i].p_filesz;
304
305 GElf_Off start = offset & -pagesize;
306 GElf_Off end = (offset + filesz + pagesize - 1) & -pagesize;
307 if (end > (GElf_Off) contents_size)
308 end = contents_size;
309 nread = (*read_memory) (arg, buffer + start,
310 (loadbase + vaddr) & -pagesize,
311 end - start, end - start);
312 if (nread <= 0)
313 goto read_error;
314 }
315
316 /* If the segments visible in memory didn't include the section
317 headers, then clear them from the file header. */
318 if (contents_size < shdrs_end)
319 {
320 if (class32)
321 {
322 ehdr.e32.e_shoff = 0;
323 ehdr.e32.e_shnum = 0;
324 ehdr.e32.e_shstrndx = 0;
325 }
326 else
327 {
328 ehdr.e64.e_shoff = 0;
329 ehdr.e64.e_shnum = 0;
330 ehdr.e64.e_shstrndx = 0;
331 }
332 }
333
334 /* This will normally have been in the first PT_LOAD segment. But it
335 conceivably could be missing, and we might have just changed it. */
336 xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
337 xlateto.d_buf = buffer;
338 if (class32)
339 {
340 xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e32;
341 xlatefrom.d_buf = &ehdr.e32;
342 if (elf32_xlatetof (&xlateto, &xlatefrom,
343 ehdr.e32.e_ident[EI_DATA]) == NULL)
344 goto libelf_error;
345 }
346 else
347 {
348 xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e64;
349 xlatefrom.d_buf = &ehdr.e64;
350 if (elf64_xlatetof (&xlateto, &xlatefrom,
351 ehdr.e64.e_ident[EI_DATA]) == NULL)
352 goto libelf_error;
353 }
354
355 free (phdrsp);
356 phdrsp = NULL;
357
358 /* Now we have the image. Open libelf on it. */
359
360 Elf *elf = elf_memory ((char *) buffer, contents_size);
361 if (elf == NULL)
362 {
363 free (buffer);
364 goto libelf_error;
365 }
366
367 elf->flags |= ELF_F_MALLOCED;
368 if (loadbasep != NULL)
369 *loadbasep = loadbase;
370 return elf;
371 }
372