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