Coverage Report

Created: 2025-07-11 06:13

/src/libbpf/elfutils/libelf/elf32_getphdr.c
Line
Count
Source (jump to first uncovered line)
1
/* Get ELF program header table.
2
   Copyright (C) 1998-2010, 2014, 2015 Red Hat, Inc.
3
   This file is part of elfutils.
4
   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
5
6
   This file is free software; you can redistribute it and/or modify
7
   it under the terms of either
8
9
     * the GNU Lesser General Public License as published by the Free
10
       Software Foundation; either version 3 of the License, or (at
11
       your option) any later version
12
13
   or
14
15
     * the GNU General Public License as published by the Free
16
       Software Foundation; either version 2 of the License, or (at
17
       your option) any later version
18
19
   or both in parallel, as here.
20
21
   elfutils is distributed in the hope that it will be useful, but
22
   WITHOUT ANY WARRANTY; without even the implied warranty of
23
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24
   General Public License for more details.
25
26
   You should have received copies of the GNU General Public License and
27
   the GNU Lesser General Public License along with this program.  If
28
   not, see <http://www.gnu.org/licenses/>.  */
29
30
#ifdef HAVE_CONFIG_H
31
# include <config.h>
32
#endif
33
34
#include <errno.h>
35
#include <stdbool.h>
36
#include <stdlib.h>
37
#include <assert.h>
38
39
#include "libelfP.h"
40
#include "common.h"
41
42
#ifndef LIBELFBITS
43
# define LIBELFBITS 32
44
#endif
45
46
ElfW2(LIBELFBITS,Phdr) *
47
__elfw2(LIBELFBITS,getphdr_wrlock) (Elf *elf)
48
0
{
49
0
  ElfW2(LIBELFBITS,Phdr) *result;
50
51
  /* If the program header entry has already been filled in the code
52
     below must already have been run.  So the class is set, too.  No
53
     need to waste any more time here.  */
54
0
  result = elf->state.ELFW(elf,LIBELFBITS).phdr;
55
0
  if (likely (result != NULL))
56
0
    return result;
57
58
0
  if (elf->class == 0)
59
0
    elf->class = ELFW(ELFCLASS,LIBELFBITS);
60
0
  else if (elf->class != ELFW(ELFCLASS,LIBELFBITS))
61
0
    {
62
0
      __libelf_seterrno (ELF_E_INVALID_CLASS);
63
0
      result = NULL;
64
0
      goto out;
65
0
    }
66
67
0
  if (likely (result == NULL))
68
0
    {
69
      /* Read the section header table.  */
70
0
      ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
71
72
      /* If no program header exists return NULL.  */
73
0
      size_t phnum;
74
0
      if (__elf_getphdrnum_rdlock (elf, &phnum) != 0)
75
0
  goto out;
76
0
      if (phnum == 0 || ehdr->e_phoff == 0)
77
0
  {
78
0
    __libelf_seterrno (ELF_E_NO_PHDR);
79
0
    goto out;
80
0
  }
81
82
      /* Check this doesn't overflow.  */
83
0
      size_t size = phnum * sizeof (ElfW2(LIBELFBITS,Phdr));
84
85
0
      if (phnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))
86
0
    || ehdr->e_phoff > elf->maximum_size
87
0
    || elf->maximum_size - ehdr->e_phoff < size)
88
0
  {
89
0
    __libelf_seterrno (ELF_E_INVALID_DATA);
90
0
    goto out;
91
0
  }
92
93
0
      if (elf->map_address != NULL)
94
0
  {
95
    /* First see whether the information in the ELF header is
96
       valid and it does not ask for too much.  */
97
0
    if (unlikely (ehdr->e_phoff >= elf->maximum_size)
98
0
        || unlikely (elf->maximum_size - ehdr->e_phoff < size))
99
0
      {
100
        /* Something is wrong.  */
101
0
        __libelf_seterrno (ELF_E_INVALID_PHDR);
102
0
        goto out;
103
0
      }
104
105
    /* All the data is already mapped.  Use it.  */
106
0
    void *file_phdr = ((char *) elf->map_address
107
0
           + elf->start_offset + ehdr->e_phoff);
108
0
    if (ehdr->e_ident[EI_DATA] == MY_ELFDATA
109
0
        && (ALLOW_UNALIGNED
110
0
      || ((uintptr_t) file_phdr
111
0
          & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0))
112
      /* Simply use the mapped data.  */
113
0
      elf->state.ELFW(elf,LIBELFBITS).phdr = file_phdr;
114
0
    else
115
0
      {
116
0
        ElfW2(LIBELFBITS,Phdr) *notcvt;
117
0
        ElfW2(LIBELFBITS,Phdr) *phdr;
118
119
        /* Allocate memory for the program headers.  We know the number
120
     of entries from the ELF header.  */
121
0
        phdr = elf->state.ELFW(elf,LIBELFBITS).phdr =
122
0
    (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
123
0
        if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
124
0
    {
125
0
      __libelf_seterrno (ELF_E_NOMEM);
126
0
      goto out;
127
0
    }
128
0
        elf->state.ELFW(elf,LIBELFBITS).phdr_flags |=
129
0
    ELF_F_MALLOCED | ELF_F_DIRTY;
130
131
        /* Now copy the data and at the same time convert the
132
     byte order.  */
133
134
0
        if (ehdr->e_ident[EI_DATA] == MY_ELFDATA)
135
0
    {
136
0
      assert (! ALLOW_UNALIGNED);
137
0
      memcpy (phdr, file_phdr, size);
138
0
    }
139
0
        else
140
0
    {
141
0
      bool copy = ! (ALLOW_UNALIGNED
142
0
         || ((uintptr_t) file_phdr
143
0
             & (__alignof__ (ElfW2(LIBELFBITS,Phdr))
144
0
          - 1)) == 0);
145
0
      if (! copy)
146
0
        notcvt = file_phdr;
147
0
      else
148
0
        {
149
0
          notcvt = (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
150
0
          if (unlikely (notcvt == NULL))
151
0
      {
152
0
        __libelf_seterrno (ELF_E_NOMEM);
153
0
        goto out;
154
0
      }
155
0
          memcpy (notcvt, file_phdr, size);
156
0
        }
157
158
0
      for (size_t cnt = 0; cnt < phnum; ++cnt)
159
0
        {
160
0
          CONVERT_TO (phdr[cnt].p_type, notcvt[cnt].p_type);
161
0
          CONVERT_TO (phdr[cnt].p_offset, notcvt[cnt].p_offset);
162
0
          CONVERT_TO (phdr[cnt].p_vaddr, notcvt[cnt].p_vaddr);
163
0
          CONVERT_TO (phdr[cnt].p_paddr, notcvt[cnt].p_paddr);
164
0
          CONVERT_TO (phdr[cnt].p_filesz, notcvt[cnt].p_filesz);
165
0
          CONVERT_TO (phdr[cnt].p_memsz, notcvt[cnt].p_memsz);
166
0
          CONVERT_TO (phdr[cnt].p_flags, notcvt[cnt].p_flags);
167
0
          CONVERT_TO (phdr[cnt].p_align, notcvt[cnt].p_align);
168
0
        }
169
170
0
      if (copy)
171
0
        free (notcvt);
172
0
    }
173
0
      }
174
0
  }
175
0
      else if (likely (elf->fildes != -1))
176
0
  {
177
    /* Allocate memory for the program headers.  We know the number
178
       of entries from the ELF header.  */
179
0
    elf->state.ELFW(elf,LIBELFBITS).phdr =
180
0
      (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
181
0
    if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
182
0
      {
183
0
        __libelf_seterrno (ELF_E_NOMEM);
184
0
        goto out;
185
0
      }
186
0
    elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_MALLOCED;
187
188
    /* Read the header.  */
189
0
    ssize_t n = pread_retry (elf->fildes,
190
0
           elf->state.ELFW(elf,LIBELFBITS).phdr, size,
191
0
           elf->start_offset + ehdr->e_phoff);
192
0
    if (unlikely ((size_t) n != size))
193
0
      {
194
        /* Severe problems.  We cannot read the data.  */
195
0
        __libelf_seterrno (ELF_E_READ_ERROR);
196
0
        free (elf->state.ELFW(elf,LIBELFBITS).phdr);
197
0
        elf->state.ELFW(elf,LIBELFBITS).phdr = NULL;
198
0
        goto out;
199
0
      }
200
201
    /* If the byte order of the file is not the same as the one
202
       of the host convert the data now.  */
203
0
    if (ehdr->e_ident[EI_DATA] != MY_ELFDATA)
204
0
      {
205
0
        ElfW2(LIBELFBITS,Phdr) *phdr
206
0
    = elf->state.ELFW(elf,LIBELFBITS).phdr;
207
208
0
        for (size_t cnt = 0; cnt < phnum; ++cnt)
209
0
    {
210
0
      CONVERT (phdr[cnt].p_type);
211
0
      CONVERT (phdr[cnt].p_offset);
212
0
      CONVERT (phdr[cnt].p_vaddr);
213
0
      CONVERT (phdr[cnt].p_paddr);
214
0
      CONVERT (phdr[cnt].p_filesz);
215
0
      CONVERT (phdr[cnt].p_memsz);
216
0
      CONVERT (phdr[cnt].p_flags);
217
0
      CONVERT (phdr[cnt].p_align);
218
0
    }
219
0
      }
220
0
  }
221
0
      else
222
0
  {
223
    /* The file descriptor was already enabled and not all data was
224
       read.  */
225
0
    __libelf_seterrno (ELF_E_FD_DISABLED);
226
0
    goto out;
227
0
  }
228
229
0
      result = elf->state.ELFW(elf,LIBELFBITS).phdr;
230
0
    }
231
232
0
 out:
233
0
  return result;
234
0
}
Unexecuted instantiation: __elf32_getphdr_wrlock
Unexecuted instantiation: __elf64_getphdr_wrlock
235
236
ElfW2(LIBELFBITS,Phdr) *
237
elfw2(LIBELFBITS,getphdr) (Elf *elf)
238
0
{
239
0
  ElfW2(LIBELFBITS,Phdr) *result;
240
241
0
  if (elf == NULL)
242
0
    return NULL;
243
244
0
  if (unlikely (elf->kind != ELF_K_ELF))
245
0
    {
246
0
      __libelf_seterrno (ELF_E_INVALID_HANDLE);
247
0
      return NULL;
248
0
    }
249
250
  /* If the program header entry has already been filled in the code
251
   * in getphdr_wrlock must already have been run.  So the class is
252
   * set, too.  No need to waste any more time here.  */
253
0
  result = elf->state.ELFW(elf,LIBELFBITS).phdr;
254
0
  if (likely (result != NULL))
255
0
    return result;
256
257
0
  rwlock_wrlock (elf->lock);
258
0
  result = __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
259
0
  rwlock_unlock (elf->lock);
260
261
0
  return result;
262
0
}
Unexecuted instantiation: elf32_getphdr
Unexecuted instantiation: elf64_getphdr
263
INTDEF(elfw2(LIBELFBITS,getphdr))