libdwfl: Sanity check partial core file dyn data read.
[platform/upstream/elfutils.git] / libdw / dwarf_begin_elf.c
1 /* Create descriptor from ELF descriptor for processing file.
2    Copyright (C) 2002-2011, 2014, 2015, 2017, 2018 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 #ifdef HAVE_CONFIG_H
30 # include <config.h>
31 #endif
32
33 #include <assert.h>
34 #include <stdbool.h>
35 #include <stddef.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <fcntl.h>
43 #include <endian.h>
44
45 #include "libelfP.h"
46 #include "libdwP.h"
47
48
49 /* Section names.  (Note .debug_str_offsets is the largest 19 chars.)  */
50 static const char dwarf_scnnames[IDX_last][19] =
51 {
52   [IDX_debug_info] = ".debug_info",
53   [IDX_debug_types] = ".debug_types",
54   [IDX_debug_abbrev] = ".debug_abbrev",
55   [IDX_debug_addr] = ".debug_addr",
56   [IDX_debug_aranges] = ".debug_aranges",
57   [IDX_debug_line] = ".debug_line",
58   [IDX_debug_line_str] = ".debug_line_str",
59   [IDX_debug_frame] = ".debug_frame",
60   [IDX_debug_loc] = ".debug_loc",
61   [IDX_debug_loclists] = ".debug_loclists",
62   [IDX_debug_pubnames] = ".debug_pubnames",
63   [IDX_debug_str] = ".debug_str",
64   [IDX_debug_str_offsets] = ".debug_str_offsets",
65   [IDX_debug_macinfo] = ".debug_macinfo",
66   [IDX_debug_macro] = ".debug_macro",
67   [IDX_debug_ranges] = ".debug_ranges",
68   [IDX_debug_rnglists] = ".debug_rnglists",
69   [IDX_gnu_debugaltlink] = ".gnu_debugaltlink"
70 };
71 #define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
72
73 static Dwarf *
74 check_section (Dwarf *result, size_t shstrndx, Elf_Scn *scn, bool inscngrp)
75 {
76   GElf_Shdr shdr_mem;
77   GElf_Shdr *shdr;
78
79   /* Get the section header data.  */
80   shdr = gelf_getshdr (scn, &shdr_mem);
81   if (shdr == NULL)
82     /* We may read /proc/PID/mem with only program headers mapped and section
83        headers out of the mapped pages.  */
84     goto err;
85
86   /* Ignore any SHT_NOBITS sections.  Debugging sections should not
87      have been stripped, but in case of a corrupt file we won't try
88      to look at the missing data.  */
89   if (unlikely (shdr->sh_type == SHT_NOBITS))
90     return result;
91
92   /* Make sure the section is part of a section group only iff we
93      really need it.  If we are looking for the global (= non-section
94      group debug info) we have to ignore all the info in section
95      groups.  If we are looking into a section group we cannot look at
96      a section which isn't part of the section group.  */
97   if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0)
98     /* Ignore the section.  */
99     return result;
100
101
102   /* We recognize the DWARF section by their names.  This is not very
103      safe and stable but the best we can do.  */
104   const char *scnname = elf_strptr (result->elf, shstrndx,
105                                     shdr->sh_name);
106   if (scnname == NULL)
107     {
108       /* The section name must be valid.  Otherwise is the ELF file
109          invalid.  */
110     err:
111       Dwarf_Sig8_Hash_free (&result->sig8_hash);
112       __libdw_seterrno (DWARF_E_INVALID_ELF);
113       free (result);
114       return NULL;
115     }
116
117   /* Recognize the various sections.  Most names start with .debug_.  */
118   size_t cnt;
119   bool gnu_compressed = false;
120   for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
121     {
122       size_t dbglen = strlen (dwarf_scnnames[cnt]);
123       size_t scnlen = strlen (scnname);
124       if (strncmp (scnname, dwarf_scnnames[cnt], dbglen) == 0
125           && (dbglen == scnlen
126               || (scnlen == dbglen + 4
127                   && strstr (scnname, ".dwo") == scnname + dbglen)))
128         break;
129       else if (scnname[0] == '.' && scnname[1] == 'z'
130                && (strncmp (&scnname[2], &dwarf_scnnames[cnt][1],
131                             dbglen - 1) == 0
132                    && (scnlen == dbglen + 1
133                        || (scnlen == dbglen + 5
134                            && strstr (scnname,
135                                       ".dwo") == scnname + dbglen + 1))))
136         {
137           gnu_compressed = true;
138           break;
139         }
140     }
141
142   if (cnt >= ndwarf_scnnames)
143     /* Not a debug section; ignore it. */
144     return result;
145
146   if (unlikely (result->sectiondata[cnt] != NULL))
147     /* A section appears twice.  That's bad.  We ignore the section.  */
148     return result;
149
150   /* We cannot know whether or not a GNU compressed section has already
151      been uncompressed or not, so ignore any errors.  */
152   if (gnu_compressed)
153     elf_compress_gnu (scn, 0, 0);
154
155   if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
156     {
157       if (elf_compress (scn, 0, 0) < 0)
158         {
159           /* It would be nice if we could fail with a specific error.
160              But we don't know if this was an essential section or not.
161              So just continue for now. See also valid_p().  */
162           return result;
163         }
164     }
165
166   /* Get the section data.  */
167   Elf_Data *data = elf_getdata (scn, NULL);
168   if (data == NULL)
169     goto err;
170
171   if (data->d_buf == NULL || data->d_size == 0)
172     /* No data actually available, ignore it. */
173     return result;
174
175   /* We can now read the section data into results. */
176   result->sectiondata[cnt] = data;
177
178   return result;
179 }
180
181
182 /* Helper function to set debugdir field.  We want to cache the dir
183    where we found this Dwarf ELF file to locate alt and dwo files.  */
184 char *
185 __libdw_debugdir (int fd)
186 {
187   /* strlen ("/proc/self/fd/") = 14 + strlen (<MAXINT>) = 10 + 1 = 25.  */
188   char devfdpath[25];
189   sprintf (devfdpath, "/proc/self/fd/%u", fd);
190   char *fdpath = realpath (devfdpath, NULL);
191   char *fddir;
192   if (fdpath != NULL && fdpath[0] == '/'
193       && (fddir = strrchr (fdpath, '/')) != NULL)
194     {
195       *++fddir = '\0';
196       return fdpath;
197     }
198   return NULL;
199 }
200
201
202 /* Check whether all the necessary DWARF information is available.  */
203 static Dwarf *
204 valid_p (Dwarf *result)
205 {
206   /* We looked at all the sections.  Now determine whether all the
207      sections with debugging information we need are there.
208
209      Require at least one section that can be read "standalone".  */
210   if (likely (result != NULL)
211       && unlikely (result->sectiondata[IDX_debug_info] == NULL
212                    && result->sectiondata[IDX_debug_line] == NULL
213                    && result->sectiondata[IDX_debug_frame] == NULL))
214     {
215       Dwarf_Sig8_Hash_free (&result->sig8_hash);
216       __libdw_seterrno (DWARF_E_NO_DWARF);
217       free (result);
218       result = NULL;
219     }
220
221   /* For dwarf_location_attr () we need a "fake" CU to indicate
222      where the "fake" attribute data comes from.  This is a block
223      inside the .debug_loc or .debug_loclists section.  */
224   if (result != NULL && result->sectiondata[IDX_debug_loc] != NULL)
225     {
226       result->fake_loc_cu = (Dwarf_CU *) calloc (1, sizeof (Dwarf_CU));
227       if (unlikely (result->fake_loc_cu == NULL))
228         {
229           Dwarf_Sig8_Hash_free (&result->sig8_hash);
230           __libdw_seterrno (DWARF_E_NOMEM);
231           free (result);
232           result = NULL;
233         }
234       else
235         {
236           result->fake_loc_cu->sec_idx = IDX_debug_loc;
237           result->fake_loc_cu->dbg = result;
238           result->fake_loc_cu->startp
239             = result->sectiondata[IDX_debug_loc]->d_buf;
240           result->fake_loc_cu->endp
241             = (result->sectiondata[IDX_debug_loc]->d_buf
242                + result->sectiondata[IDX_debug_loc]->d_size);
243         }
244     }
245
246   if (result != NULL && result->sectiondata[IDX_debug_loclists] != NULL)
247     {
248       result->fake_loclists_cu = (Dwarf_CU *) calloc (1, sizeof (Dwarf_CU));
249       if (unlikely (result->fake_loclists_cu == NULL))
250         {
251           Dwarf_Sig8_Hash_free (&result->sig8_hash);
252           __libdw_seterrno (DWARF_E_NOMEM);
253           free (result->fake_loc_cu);
254           free (result);
255           result = NULL;
256         }
257       else
258         {
259           result->fake_loclists_cu->sec_idx = IDX_debug_loclists;
260           result->fake_loclists_cu->dbg = result;
261           result->fake_loclists_cu->startp
262             = result->sectiondata[IDX_debug_loclists]->d_buf;
263           result->fake_loclists_cu->endp
264             = (result->sectiondata[IDX_debug_loclists]->d_buf
265                + result->sectiondata[IDX_debug_loclists]->d_size);
266         }
267     }
268
269   /* For DW_OP_constx/GNU_const_index and DW_OP_addrx/GNU_addr_index
270      the dwarf_location_attr () will need a "fake" address CU to
271      indicate where the attribute data comes from.  This is a just
272      inside the .debug_addr section, if it exists.  */
273   if (result != NULL && result->sectiondata[IDX_debug_addr] != NULL)
274     {
275       result->fake_addr_cu = (Dwarf_CU *) calloc (1, sizeof (Dwarf_CU));
276       if (unlikely (result->fake_addr_cu == NULL))
277         {
278           Dwarf_Sig8_Hash_free (&result->sig8_hash);
279           __libdw_seterrno (DWARF_E_NOMEM);
280           free (result->fake_loc_cu);
281           free (result->fake_loclists_cu);
282           free (result);
283           result = NULL;
284         }
285       else
286         {
287           result->fake_addr_cu->sec_idx = IDX_debug_addr;
288           result->fake_addr_cu->dbg = result;
289           result->fake_addr_cu->startp
290             = result->sectiondata[IDX_debug_addr]->d_buf;
291           result->fake_addr_cu->endp
292             = (result->sectiondata[IDX_debug_addr]->d_buf
293                + result->sectiondata[IDX_debug_addr]->d_size);
294         }
295     }
296
297   if (result != NULL)
298     result->debugdir = __libdw_debugdir (result->elf->fildes);
299
300   return result;
301 }
302
303
304 static Dwarf *
305 global_read (Dwarf *result, Elf *elf, size_t shstrndx)
306 {
307   Elf_Scn *scn = NULL;
308
309   while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
310     result = check_section (result, shstrndx, scn, false);
311
312   return valid_p (result);
313 }
314
315
316 static Dwarf *
317 scngrp_read (Dwarf *result, Elf *elf, size_t shstrndx, Elf_Scn *scngrp)
318 {
319   GElf_Shdr shdr_mem;
320   GElf_Shdr *shdr = gelf_getshdr (scngrp, &shdr_mem);
321   if (shdr == NULL)
322     {
323       Dwarf_Sig8_Hash_free (&result->sig8_hash);
324       __libdw_seterrno (DWARF_E_INVALID_ELF);
325       free (result);
326       return NULL;
327     }
328
329   if ((shdr->sh_flags & SHF_COMPRESSED) != 0
330       && elf_compress (scngrp, 0, 0) < 0)
331     {
332       Dwarf_Sig8_Hash_free (&result->sig8_hash);
333       __libdw_seterrno (DWARF_E_COMPRESSED_ERROR);
334       free (result);
335       return NULL;
336     }
337
338   /* SCNGRP is the section descriptor for a section group which might
339      contain debug sections.  */
340   Elf_Data *data = elf_getdata (scngrp, NULL);
341   if (data == NULL)
342     {
343       /* We cannot read the section content.  Fail!  */
344       Dwarf_Sig8_Hash_free (&result->sig8_hash);
345       free (result);
346       return NULL;
347     }
348
349   /* The content of the section is a number of 32-bit words which
350      represent section indices.  The first word is a flag word.  */
351   Elf32_Word *scnidx = (Elf32_Word *) data->d_buf;
352   size_t cnt;
353   for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt)
354     {
355       Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
356       if (scn == NULL)
357         {
358           /* A section group refers to a non-existing section.  Should
359              never happen.  */
360           Dwarf_Sig8_Hash_free (&result->sig8_hash);
361           __libdw_seterrno (DWARF_E_INVALID_ELF);
362           free (result);
363           return NULL;
364         }
365
366       result = check_section (result, shstrndx, scn, true);
367       if (result == NULL)
368         break;
369     }
370
371   return valid_p (result);
372 }
373
374
375 Dwarf *
376 dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
377 {
378   GElf_Ehdr *ehdr;
379   GElf_Ehdr ehdr_mem;
380
381   /* Get the ELF header of the file.  We need various pieces of
382      information from it.  */
383   ehdr = gelf_getehdr (elf, &ehdr_mem);
384   if (ehdr == NULL)
385     {
386       if (elf_kind (elf) != ELF_K_ELF)
387         __libdw_seterrno (DWARF_E_NOELF);
388       else
389         __libdw_seterrno (DWARF_E_GETEHDR_ERROR);
390
391       return NULL;
392     }
393
394
395   /* Default memory allocation size.  */
396   size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *);
397   assert (sizeof (struct Dwarf) < mem_default_size);
398
399   /* Allocate the data structure.  */
400   Dwarf *result = (Dwarf *) calloc (1, sizeof (Dwarf) + mem_default_size);
401   if (unlikely (result == NULL)
402       || unlikely (Dwarf_Sig8_Hash_init (&result->sig8_hash, 11) < 0))
403     {
404       free (result);
405       __libdw_seterrno (DWARF_E_NOMEM);
406       return NULL;
407     }
408
409   /* Fill in some values.  */
410   if ((BYTE_ORDER == LITTLE_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
411       || (BYTE_ORDER == BIG_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
412     result->other_byte_order = true;
413
414   result->elf = elf;
415   result->alt_fd = -1;
416
417   /* Initialize the memory handling.  */
418   result->mem_default_size = mem_default_size;
419   result->oom_handler = __libdw_oom;
420   result->mem_tail = (struct libdw_memblock *) (result + 1);
421   result->mem_tail->size = (result->mem_default_size
422                             - offsetof (struct libdw_memblock, mem));
423   result->mem_tail->remaining = result->mem_tail->size;
424   result->mem_tail->prev = NULL;
425
426   if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
427     {
428       /* All sections are recognized by name, so pass the section header
429          string index along to easily get the section names.  */
430       size_t shstrndx;
431       if (elf_getshdrstrndx (elf, &shstrndx) != 0)
432         {
433           Dwarf_Sig8_Hash_free (&result->sig8_hash);
434           __libdw_seterrno (DWARF_E_INVALID_ELF);
435           free (result);
436           return NULL;
437         }
438
439       /* If the caller provides a section group we get the DWARF
440          sections only from this setion group.  Otherwise we search
441          for the first section with the required name.  Further
442          sections with the name are ignored.  The DWARF specification
443          does not really say this is allowed.  */
444       if (scngrp == NULL)
445         return global_read (result, elf, shstrndx);
446       else
447         return scngrp_read (result, elf, shstrndx, scngrp);
448     }
449   else if (cmd == DWARF_C_WRITE)
450     {
451       Dwarf_Sig8_Hash_free (&result->sig8_hash);
452       __libdw_seterrno (DWARF_E_UNIMPL);
453       free (result);
454       return NULL;
455     }
456
457   Dwarf_Sig8_Hash_free (&result->sig8_hash);
458   __libdw_seterrno (DWARF_E_INVALID_CMD);
459   free (result);
460   return NULL;
461 }
462 INTDEF(dwarf_begin_elf)