Home | History | Annotate | Download | only in libdwfl
      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 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   void *phdrsp = NULL;
     69 
     70   /* First read in the file header and check its sanity.  */
     71 
     72   const size_t initial_bufsize = 256;
     73   unsigned char *buffer = malloc (initial_bufsize);
     74   if (unlikely (buffer == NULL))
     75     {
     76     no_memory:
     77       __libdwfl_seterrno (DWFL_E_NOMEM);
     78       return NULL;
     79     }
     80 
     81   ssize_t nread = (*read_memory) (arg, buffer, ehdr_vma,
     82 				  sizeof (Elf32_Ehdr), initial_bufsize);
     83   if (nread <= 0)
     84     {
     85     read_error:
     86       free (buffer);
     87       free (phdrsp);
     88       __libdwfl_seterrno (nread < 0 ? DWFL_E_ERRNO : DWFL_E_TRUNCATED);
     89       return NULL;
     90     }
     91 
     92   if (memcmp (buffer, ELFMAG, SELFMAG) != 0)
     93     {
     94     bad_elf:
     95       free (buffer);
     96       free (phdrsp);
     97       __libdwfl_seterrno (DWFL_E_BADELF);
     98       return NULL;
     99     }
    100 
    101   /* Extract the information we need from the file header.  */
    102 
    103   union
    104   {
    105     Elf32_Ehdr e32;
    106     Elf64_Ehdr e64;
    107   } ehdr;
    108   Elf_Data xlatefrom =
    109     {
    110       .d_type = ELF_T_EHDR,
    111       .d_buf = buffer,
    112       .d_version = EV_CURRENT,
    113     };
    114   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   GElf_Off phoff;
    123   uint_fast16_t phnum;
    124   uint_fast16_t phentsize;
    125   GElf_Off shdrs_end;
    126 
    127   switch (buffer[EI_CLASS])
    128     {
    129     case ELFCLASS32:
    130       xlatefrom.d_size = sizeof (Elf32_Ehdr);
    131       if (elf32_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL)
    132 	{
    133 	libelf_error:
    134 	  __libdwfl_seterrno (DWFL_E_LIBELF);
    135 	  return NULL;
    136 	}
    137       phoff = ehdr.e32.e_phoff;
    138       phnum = ehdr.e32.e_phnum;
    139       phentsize = ehdr.e32.e_phentsize;
    140       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       shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize;
    148       break;
    149 
    150     case ELFCLASS64:
    151       xlatefrom.d_size = sizeof (Elf64_Ehdr);
    152       if (elf64_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL)
    153 	goto libelf_error;
    154       phoff = ehdr.e64.e_phoff;
    155       phnum = ehdr.e64.e_phnum;
    156       phentsize = ehdr.e64.e_phentsize;
    157       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       shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize;
    161       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   xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR;
    172   xlatefrom.d_size = phnum * phentsize;
    173 
    174   if ((size_t) nread >= phoff + phnum * phentsize)
    175     /* We already have all the phdrs from the initial read.  */
    176     xlatefrom.d_buf = buffer + phoff;
    177   else
    178     {
    179       /* Read in the program headers.  */
    180 
    181       if (initial_bufsize < (size_t)phnum * phentsize)
    182 	{
    183 	  unsigned char *newbuf = realloc (buffer, phnum * phentsize);
    184 	  if (newbuf == NULL)
    185 	    {
    186 	      free (buffer);
    187 	      free (phdrsp);
    188 	      goto no_memory;
    189 	    }
    190 	  buffer = newbuf;
    191 	}
    192       nread = (*read_memory) (arg, buffer, ehdr_vma + phoff,
    193 			      phnum * phentsize, phnum * phentsize);
    194       if (nread <= 0)
    195 	goto read_error;
    196 
    197       xlatefrom.d_buf = buffer;
    198     }
    199 
    200   bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
    201   size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
    202   if (unlikely (phnum > SIZE_MAX / phdr_size))
    203     {
    204       free (buffer);
    205       goto no_memory;
    206     }
    207   const size_t phdrsp_bytes = phnum * phdr_size;
    208   phdrsp = malloc (phdrsp_bytes);
    209   if (unlikely (phdrsp == NULL))
    210     {
    211       free (buffer);
    212       goto no_memory;
    213     }
    214 
    215   xlateto.d_buf = phdrsp;
    216   xlateto.d_size = phdrsp_bytes;
    217 
    218   /* Scan for PT_LOAD segments to find the total size of the file image.  */
    219   size_t contents_size = 0;
    220   GElf_Off segments_end = 0;
    221   GElf_Off segments_end_mem = 0;
    222   GElf_Addr loadbase = ehdr_vma;
    223   bool found_base = false;
    224   Elf32_Phdr (*p32)[phnum] = phdrsp;
    225   Elf64_Phdr (*p64)[phnum] = phdrsp;
    226   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       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 	  if (((vaddr - offset) & (pagesize - 1)) != 0)
    237 	    return true;
    238 
    239 	  GElf_Off segment_end = ((offset + filesz + pagesize - 1)
    240 				  & -pagesize);
    241 
    242 	  if (segment_end > (GElf_Off) contents_size)
    243 	    contents_size = segment_end;
    244 
    245 	  if (!found_base && (offset & -pagesize) == 0)
    246 	    {
    247 	      loadbase = ehdr_vma - (vaddr & -pagesize);
    248 	      found_base = true;
    249 	    }
    250 
    251 	  segments_end = offset + filesz;
    252 	  segments_end_mem = offset + memsz;
    253 	  return false;
    254 	}
    255 
    256     case ELFCLASS32:
    257       if (elf32_xlatetom (&xlateto, &xlatefrom,
    258 			  ehdr.e32.e_ident[EI_DATA]) == NULL)
    259 	goto libelf_error;
    260       for (uint_fast16_t i = 0; i < phnum; ++i)
    261 	if ((*p32)[i].p_type == PT_LOAD)
    262 	  if (handle_segment ((*p32)[i].p_vaddr, (*p32)[i].p_offset,
    263 			      (*p32)[i].p_filesz, (*p32)[i].p_memsz))
    264 	    goto bad_elf;
    265       break;
    266 
    267     case ELFCLASS64:
    268       if (elf64_xlatetom (&xlateto, &xlatefrom,
    269 			  ehdr.e64.e_ident[EI_DATA]) == NULL)
    270 	goto libelf_error;
    271       for (uint_fast16_t i = 0; i < phnum; ++i)
    272 	if ((*p64)[i].p_type == PT_LOAD)
    273 	  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     default:
    279       abort ();
    280       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   if ((GElf_Off) contents_size > segments_end
    288       && (GElf_Off) contents_size >= shdrs_end
    289       && segments_end == segments_end_mem)
    290     {
    291       contents_size = segments_end;
    292       if ((GElf_Off) contents_size < shdrs_end)
    293 	contents_size = shdrs_end;
    294     }
    295   else
    296     contents_size = segments_end;
    297 
    298   free (buffer);
    299 
    300   /* Now we know the size of the whole image we want read in.  */
    301   buffer = calloc (1, contents_size);
    302   if (buffer == NULL)
    303     {
    304       free (phdrsp);
    305       goto no_memory;
    306     }
    307 
    308   switch (ehdr.e32.e_ident[EI_CLASS])
    309     {
    310       /* Reads the given segment.  Returns true if reading fails,
    311 	 false otherwise.  */
    312       inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
    313 				  GElf_Xword filesz)
    314 	{
    315 	  GElf_Off start = offset & -pagesize;
    316 	  GElf_Off end = (offset + filesz + pagesize - 1) & -pagesize;
    317 	  if (end > (GElf_Off) contents_size)
    318 	    end = contents_size;
    319 	  nread = (*read_memory) (arg, buffer + start,
    320 				  (loadbase + vaddr) & -pagesize,
    321 				  end - start, end - start);
    322 	  return nread <= 0;
    323 	}
    324 
    325     case ELFCLASS32:
    326       for (uint_fast16_t i = 0; i < phnum; ++i)
    327 	if ((*p32)[i].p_type == PT_LOAD)
    328 	  if (handle_segment ((*p32)[i].p_vaddr, (*p32)[i].p_offset,
    329 			      (*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       if (contents_size < shdrs_end)
    335 	{
    336 	  ehdr.e32.e_shoff = 0;
    337 	  ehdr.e32.e_shnum = 0;
    338 	  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       xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
    344       xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e32;
    345       xlatefrom.d_buf = &ehdr.e32;
    346       xlateto.d_buf = buffer;
    347       if (elf32_xlatetof (&xlateto, &xlatefrom,
    348 			  ehdr.e32.e_ident[EI_DATA]) == NULL)
    349 	goto libelf_error;
    350       break;
    351 
    352     case ELFCLASS64:
    353       for (uint_fast16_t i = 0; i < phnum; ++i)
    354 	if ((*p64)[i].p_type == PT_LOAD)
    355 	  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       if (contents_size < shdrs_end)
    362 	{
    363 	  ehdr.e64.e_shoff = 0;
    364 	  ehdr.e64.e_shnum = 0;
    365 	  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       xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
    371       xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e64;
    372       xlatefrom.d_buf = &ehdr.e64;
    373       xlateto.d_buf = buffer;
    374       if (elf64_xlatetof (&xlateto, &xlatefrom,
    375 			  ehdr.e64.e_ident[EI_DATA]) == NULL)
    376 	goto libelf_error;
    377       break;
    378 
    379     default:
    380       abort ();
    381       break;
    382     }
    383 
    384   free (phdrsp);
    385   phdrsp = NULL;
    386 
    387   /* Now we have the image.  Open libelf on it.  */
    388 
    389   Elf *elf = elf_memory ((char *) buffer, contents_size);
    390   if (elf == NULL)
    391     {
    392       free (buffer);
    393       goto libelf_error;
    394     }
    395 
    396   elf->flags |= ELF_F_MALLOCED;
    397   if (loadbasep != NULL)
    398     *loadbasep = loadbase;
    399   return elf;
    400 }
    401