Bug Summary

File:src/usr.sbin/crunchgen/elf_hide.c
Warning:line 261, column 28
Access to field 'sh_offset' results in a dereference of a null pointer (loaded from variable 'pshdr')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name elf_hide.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/crunchgen/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/crunchgen/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/crunchgen/elf_hide.c
1/* $OpenBSD: elf_hide.c,v 1.11 2017/10/29 08:45:53 mpi Exp $ */
2
3/*
4 * Copyright (c) 1997 Dale Rahn.
5 * All rights reserved.
6 *
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/types.h>
30#include <sys/mman.h>
31#include <sys/stat.h>
32
33#include <elf.h>
34#include <err.h>
35#include <errno(*__errno()).h>
36#include <fcntl.h>
37#include <unistd.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include "mangle.h"
42
43extern int elf_mangle;
44
45void load_strtab(Elf_EhdrElf64_Ehdr * pehdr, char *pexe);
46void dump_strtab(void);
47char *get_str(int indx);
48
49void load_symtab(Elf_EhdrElf64_Ehdr * pehdr, char *pexe);
50void dump_symtab(Elf_ShdrElf64_Shdr * symsect, Elf_SymElf64_Sym * symtab, int symtabsize);
51void fprint_str(FILE * channel, int indx);
52
53void load_shstr_tab(Elf_EhdrElf64_Ehdr * pehdr, char *pexe);
54char *get_shstr(int indx);
55void fprint_shstr(FILE * channel, int indx);
56
57void hide_sym(Elf_EhdrElf64_Ehdr * ehdr, Elf_ShdrElf64_Shdr * symsect,
58 Elf_SymElf64_Sym * symtab, int symtabsize, int symtabsecnum);
59void reorder_syms(Elf_EhdrElf64_Ehdr * ehdr, Elf_ShdrElf64_Shdr * symsect,
60 Elf_SymElf64_Sym * symtab, int symtabsize, int symtabsecnum);
61typedef long Symmap;
62void renum_reloc_syms(Elf_EhdrElf64_Ehdr * ehdr, Symmap * symmap,
63 int symtabsecnum);
64void elf_hide(int pfile, char *p);
65
66
67char *pexe;
68
69void
70elf_hide(int pfile, char *p)
71{
72 Elf_EhdrElf64_Ehdr *pehdr;
73#ifdef DEBUG
74 Elf_ShdrElf64_Shdr *pshdr;
75 Elf_PhdrElf64_Phdr *pphdr;
76 int i;
77#endif
78
79 pexe = p;
80 pehdr = (Elf_EhdrElf64_Ehdr *) pexe;
81
82#ifdef DEBUG
83 printf("elf header\n");
84 printf("e_type %x\n", pehdr->e_type);
85 printf("e_machine %x\n", pehdr->e_machine);
86 printf("e_version %x\n", pehdr->e_version);
87 printf("e_entry %x\n", pehdr->e_entry);
88 printf("e_phoff %x\n", pehdr->e_phoff);
89 printf("e_shoff %x\n", pehdr->e_shoff);
90 printf("e_flags %x\n", pehdr->e_flags);
91 printf("e_ehsize %x\n", pehdr->e_ehsize);
92 printf("e_phentsize %x\n", pehdr->e_phentsize);
93 printf("e_phnum %x\n", pehdr->e_phnum);
94 printf("e_shentsize %x\n", pehdr->e_shentsize);
95 printf("e_shnum %x\n", pehdr->e_shnum);
96 printf("e_shstrndx %x\n", pehdr->e_shstrndx);
97#endif
98
99 load_shstr_tab(pehdr, pexe);
100#ifdef DEBUG
101 for (i = 0; i < pehdr->e_shnum; i++) {
102 pshdr = (Elf_PhdrElf64_Phdr *) (pexe + pehdr->e_shoff +
103 (i * pehdr->e_shentsize));
104
105 printf("section header %d\n", i);
106 printf("sh_name %x ", pshdr->sh_name);
107 fprint_shstr(stdout(&__sF[1]), pshdr->sh_name);
108 printf("\n");
109 printf("sh_type %x\n", pshdr->sh_type);
110 printf("sh_flags %x\n", pshdr->sh_flags);
111 printf("sh_addr %x\n", pshdr->sh_addr);
112 printf("sh_offset %x\n", pshdr->sh_offset);
113 printf("sh_size %x\n", pshdr->sh_size);
114 printf("sh_link %x\n", pshdr->sh_link);
115 printf("sh_info %x\n", pshdr->sh_info);
116 printf("sh_addralign %x\n", pshdr->sh_addralign);
117 printf("sh_entsize %x\n", pshdr->sh_entsize);
118 }
119#endif /* DEBUG */
120
121#ifdef DEBUG
122 for (i = 0; i < pehdr->e_phnum; i++) {
123 pshdr = (Elf_PhdrElf64_Phdr *) (pexe + pehdr->e_phoff +
124 (i * pehdr->e_phentsize));
125
126 printf("program header %d\n", i);
127 printf("p_type %x\n", pphdr->p_type);
128 printf("p_offset %x\n", pphdr->p_offset);
129 printf("p_vaddr %x\n", pphdr->p_vaddr);
130 printf("p_paddr %x\n", pphdr->p_paddr);
131 printf("p_filesz %x\n", pphdr->p_filesz);
132 printf("p_memsz %x\n", pphdr->p_memsz);
133 printf("p_flags %x\n", pphdr->p_flags);
134 printf("p_align %x\n", pphdr->p_align);
135 }
136#endif /* DEBUG */
137#if 0
138 for (i = 0; i < pehdr->e_shnum; i++) {
139 pshdr = (Elf_PhdrElf64_Phdr *) (pexe + pehdr->e_shoff +
140 (i * pehdr->e_shentsize));
141 if (strcmp(".strtab", get_shstr(pshdr->sh_name)) == 0)
142 break;
143 }
144 fprint_shstr(stdout(&__sF[1]), pshdr->sh_name);
145 printf("\n");
146#endif
147
148 load_strtab(pehdr, pexe);
1
Calling 'load_strtab'
149 load_symtab(pehdr, pexe);
150 close(pfile);
151}
152char *shstrtab;
153
154void
155load_shstr_tab(Elf_EhdrElf64_Ehdr * pehdr, char *pexe)
156{
157 Elf_ShdrElf64_Shdr *pshdr;
158 shstrtab = NULL((void *)0);
159 if (pehdr->e_shstrndx == 0)
160 return;
161 pshdr = (Elf_ShdrElf64_Shdr *) (pexe + pehdr->e_shoff +
162 (pehdr->e_shstrndx * pehdr->e_shentsize));
163
164 shstrtab = (char *) (pexe + pshdr->sh_offset);
165}
166
167void
168fprint_shstr(FILE * channel, int indx)
169{
170 if (shstrtab != NULL((void *)0))
171 fprintf(channel, "\"%s\"", &(shstrtab[indx]));
172}
173
174char *
175get_shstr(int indx)
176{
177 return &(shstrtab[indx]);
178}
179
180void
181load_symtab(Elf_EhdrElf64_Ehdr * pehdr, char *pexe)
182{
183 Elf_SymElf64_Sym *symtab;
184 Elf_ShdrElf64_Shdr *symsect;
185 int symtabsize;
186 Elf_ShdrElf64_Shdr *psymshdr;
187 Elf_ShdrElf64_Shdr *pshdr;
188#ifdef DEBUG
189 char *shname;
190#endif
191 int i;
192
193 symtab = NULL((void *)0);
194 for (i = 0; i < pehdr->e_shnum; i++) {
195 pshdr = (Elf_ShdrElf64_Shdr *) (pexe + pehdr->e_shoff +
196 (i * pehdr->e_shentsize));
197 if (SHT_REL9 != pshdr->sh_type && SHT_RELA4 != pshdr->sh_type)
198 continue;
199 psymshdr = (Elf_ShdrElf64_Shdr *) (pexe + pehdr->e_shoff +
200 (pshdr->sh_link * pehdr->e_shentsize));
201#ifdef DEBUG
202 fprint_shstr(stdout(&__sF[1]), pshdr->sh_name);
203 printf("\n");
204#endif
205 symtab = (Elf_SymElf64_Sym *) (pexe + psymshdr->sh_offset);
206 symsect = psymshdr;
207 symtabsize = psymshdr->sh_size;
208
209#ifdef DEBUG
210 dump_symtab(symsect, symtab, symtabsize);
211#endif
212 hide_sym(pehdr, symsect, symtab, symtabsize, pshdr->sh_link);
213 }
214
215}
216
217void
218dump_symtab(Elf_ShdrElf64_Shdr * symsect, Elf_SymElf64_Sym * symtab, int symtabsize)
219{
220 int i;
221 Elf_SymElf64_Sym *psymtab;
222
223 for (i = 0; i < (symtabsize / sizeof(Elf_SymElf64_Sym)); i++) {
224 psymtab = &(symtab[i]);
225 if ((psymtab->st_info & 0xf0) == 0x10 &&
226 (psymtab->st_shndx != SHN_UNDEF0)) {
227 printf("symbol %d:\n", i);
228 printf("st_name %x \"%s\"\n", psymtab->st_name,
229 get_str(psymtab->st_name));
230 printf("st_value %llx\n", (unsigned long long)psymtab->st_value);
231 printf("st_size %llx\n", (unsigned long long)psymtab->st_size);
232 printf("st_info %x\n", psymtab->st_info);
233 printf("st_other %x\n", psymtab->st_other);
234 printf("st_shndx %x\n", psymtab->st_shndx);
235 }
236 }
237}
238
239char *strtab;
240int strtabsize;
241void
242load_strtab(Elf_EhdrElf64_Ehdr * pehdr, char *pexe)
243{
244 Elf_ShdrElf64_Shdr *pshdr = NULL((void *)0);
2
'pshdr' initialized to a null pointer value
245 char *shname;
246 int i;
247 strtab = NULL((void *)0);
248 for (i = 0; i < pehdr->e_shnum; i++) {
3
Assuming 'i' is >= field 'e_shnum'
4
Loop condition is false. Execution continues on line 261
249 pshdr = (Elf_ShdrElf64_Shdr *) (pexe + pehdr->e_shoff +
250 (i * pehdr->e_shentsize));
251
252 shname = get_shstr(pshdr->sh_name);
253 if (strcmp(".strtab", shname) == 0)
254 break;
255 }
256#ifdef DEBUG
257 fprint_shstr(stdout(&__sF[1]), pshdr->sh_name);
258 printf("\n");
259#endif
260
261 strtab = (char *) (pexe + pshdr->sh_offset);
5
Access to field 'sh_offset' results in a dereference of a null pointer (loaded from variable 'pshdr')
262
263 strtabsize = pshdr->sh_size;
264
265#ifdef DEBUG
266 dump_strtab();
267#endif
268}
269
270void
271dump_strtab()
272{
273 int index;
274 char *pstr;
275 char *pnstr;
276 int i = 0;
277 index = 0;
278 pstr = strtab;
279 while (index < strtabsize) {
280 printf("string %x: \"%s\"\n", i, pstr);
281 pnstr = pstr + strlen(pstr) + 1;
282 index = pnstr - strtab;
283 pstr = pnstr;
284 i++;
285 }
286
287}
288
289void
290fprint_str(FILE * channel, int indx)
291{
292 if (strtab != NULL((void *)0))
293 fprintf(channel, "\"%s\"", &(strtab[indx]));
294}
295
296char *
297get_str(int indx)
298{
299 return &(strtab[indx]);
300}
301
302int in_keep_list(char *symbol);
303
304void
305hide_sym(Elf_EhdrElf64_Ehdr * ehdr, Elf_ShdrElf64_Shdr * symsect,
306 Elf_SymElf64_Sym * symtab, int symtabsize, int symtabsecnum)
307{
308 int i;
309 unsigned char info;
310 Elf_SymElf64_Sym *psymtab;
311
312 for (i = 0; i < (symtabsize / sizeof(Elf_SymElf64_Sym)); i++) {
313 psymtab = &(symtab[i]);
314 if ((psymtab->st_info & 0xf0) == 0x10 &&
315 (psymtab->st_shndx != SHN_UNDEF0)) {
316 if (in_keep_list(get_str(psymtab->st_name)))
317 continue;
318#ifdef DEBUG
319 printf("symbol %d:\n", i);
320 printf("st_name %x \"%s\"\n", psymtab->st_name,
321 get_str(psymtab->st_name));
322 printf("st_info %x\n", psymtab->st_info);
323#endif
324 if (!elf_mangle) {
325 info = psymtab->st_info;
326 info = info & 0xf;
327 psymtab->st_info = info;
328 } else {
329 mangle_str(get_str(psymtab->st_name));
330 }
331#ifdef DEBUG
332 printf("st_info %x\n", psymtab->st_info);
333#endif
334 }
335 }
336 reorder_syms(ehdr, symsect, symtab, symtabsize, symtabsecnum);
337}
338
339void
340reorder_syms(Elf_EhdrElf64_Ehdr * ehdr, Elf_ShdrElf64_Shdr * symsect,
341 Elf_SymElf64_Sym * symtab, int symtabsize, int symtabsecnum)
342{
343 int i;
344 int nsyms;
345 int cursym;
346 Elf_SymElf64_Sym *tmpsymtab;
347 Symmap *symmap;
348
349
350 nsyms = symtabsize / sizeof(Elf_SymElf64_Sym);
351
352 tmpsymtab = calloc(1, symtabsize);
353 symmap = calloc(nsyms, sizeof(Symmap));
354 if (!tmpsymtab || !symmap)
355 errc(5, ENOMEM12, "calloc");
356
357 bcopy(symtab, tmpsymtab, symtabsize);
358
359 cursym = 1;
360 for (i = 1; i < nsyms; i++) {
361 if ((tmpsymtab[i].st_info & 0xf0) == 0x00) {
362#ifdef DEBUG
363 printf("copying l o%d n%d <%s>\n", i, cursym,
364 get_str(tmpsymtab[i].st_name));
365#endif
366 bcopy(&(tmpsymtab[i]), &(symtab[cursym]),
367 sizeof(Elf_SymElf64_Sym));
368 symmap[i] = cursym;
369 cursym++;
370 }
371 }
372 symsect->sh_info = cursym;
373 for (i = 1; i < nsyms; i++) {
374 if ((tmpsymtab[i].st_info & 0xf0) != 0x00) {
375#ifdef DEBUG
376 printf("copying nl o%d n%d <%s>\n", i, cursym,
377 get_str(tmpsymtab[i].st_name));
378#endif
379 bcopy(&(tmpsymtab[i]), &(symtab[cursym]),
380 sizeof(Elf_SymElf64_Sym));
381 symmap[i] = cursym;
382 cursym++;
383 }
384 }
385 if (cursym != nsyms) {
386 printf("miscounted symbols somewhere c %d n %d \n",
387 cursym, nsyms);
388 exit(5);
389 }
390 renum_reloc_syms(ehdr, symmap, symtabsecnum);
391 free(tmpsymtab);
392 free(symmap);
393}
394
395void
396renum_reloc_syms(Elf_EhdrElf64_Ehdr * ehdr, Symmap * symmap, int symtabsecnum)
397{
398 Elf_ShdrElf64_Shdr *pshdr;
399 int i, j;
400 int num_reloc;
401 Elf_RelElf64_Rel *prel;
402 Elf_RelAElf64_Rela *prela;
403 int symnum;
404
405 for (i = 0; i < ehdr->e_shnum; i++) {
406 pshdr = (Elf_ShdrElf64_Shdr *) (pexe + ehdr->e_shoff +
407 (i * ehdr->e_shentsize));
408 if ((pshdr->sh_type == SHT_RELA4) &&
409 pshdr->sh_link == symtabsecnum) {
410
411#ifdef DEBUG
412 printf("section %d has rela relocations in symtab\n", i);
413#endif
414 prela = (Elf_RelAElf64_Rela *) (pexe + pshdr->sh_offset);
415 num_reloc = pshdr->sh_size / sizeof(Elf_RelAElf64_Rela);
416 for (j = 0; j < num_reloc; j++) {
417 symnum = ELF_R_SYM(prela[j].r_info)((prela[j].r_info) >> 32);
418#ifdef DEBUG
419 printf("sym num o %d n %d\n", symnum,
420 symmap[symnum]);
421#endif
422 prela[j].r_info = ELF_R_INFO(symmap[symnum],(((symmap[symnum]) << 32) + (__uint32_t)(((prela[j].r_info
) & 0xFFFFFFFF)))
423 ELF_R_TYPE(prela[j].r_info))(((symmap[symnum]) << 32) + (__uint32_t)(((prela[j].r_info
) & 0xFFFFFFFF)))
;
424 }
425 }
426 if ((pshdr->sh_type == SHT_REL9) &&
427 pshdr->sh_link == symtabsecnum) {
428#ifdef DEBUG
429 printf("section %d has rel relocations in symtab\n", i);
430#endif
431 prel = (Elf_RelElf64_Rel *) (pexe + pshdr->sh_offset);
432 num_reloc = pshdr->sh_size / sizeof(Elf_RelElf64_Rel);
433 for (j = 0; j < num_reloc; j++) {
434 symnum = ELF_R_SYM(prel[j].r_info)((prel[j].r_info) >> 32);
435#ifdef DEBUG
436 printf("sym num o %d n %d\n", symnum,
437 symmap[symnum]);
438#endif
439 prel[j].r_info = ELF_R_INFO(symmap[symnum],(((symmap[symnum]) << 32) + (__uint32_t)(((prel[j].r_info
) & 0xFFFFFFFF)))
440 ELF_R_TYPE(prel[j].r_info))(((symmap[symnum]) << 32) + (__uint32_t)(((prel[j].r_info
) & 0xFFFFFFFF)))
;
441 }
442 }
443 }
444
445}