Skip to content

Commit b4c0114

Browse files
committed
- limit the number of program and section header number of sections to be
processed to avoid excessive processing time. - if a bad note is found, return 0 to stop processing immediately.
1 parent 4b2de03 commit b4c0114

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

Diff for: src/elfclass.h

+16-8
Original file line numberDiff line numberDiff line change
@@ -35,29 +35,37 @@
3535
switch (type) {
3636
#ifdef ELFCORE
3737
case ET_CORE:
38+
phnum = elf_getu16(swap, elfhdr.e_phnum);
39+
if (phnum > MAX_PHNUM)
40+
return toomany(ms, "program", phnum);
3841
flags |= FLAGS_IS_CORE;
3942
if (dophn_core(ms, clazz, swap, fd,
40-
(off_t)elf_getu(swap, elfhdr.e_phoff),
41-
elf_getu16(swap, elfhdr.e_phnum),
43+
(off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
4244
(size_t)elf_getu16(swap, elfhdr.e_phentsize),
4345
fsize, &flags) == -1)
4446
return -1;
4547
break;
4648
#endif
4749
case ET_EXEC:
4850
case ET_DYN:
51+
phnum = elf_getu16(swap, elfhdr.e_phnum);
52+
if (phnum > MAX_PHNUM)
53+
return toomany(ms, "program", phnum);
54+
shnum = elf_getu16(swap, elfhdr.e_shnum);
55+
if (shnum > MAX_SHNUM)
56+
return toomany(ms, "section", shnum);
4957
if (dophn_exec(ms, clazz, swap, fd,
50-
(off_t)elf_getu(swap, elfhdr.e_phoff),
51-
elf_getu16(swap, elfhdr.e_phnum),
58+
(off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
5259
(size_t)elf_getu16(swap, elfhdr.e_phentsize),
53-
fsize, &flags, elf_getu16(swap, elfhdr.e_shnum))
54-
== -1)
60+
fsize, &flags, shnum) == -1)
5561
return -1;
5662
/*FALLTHROUGH*/
5763
case ET_REL:
64+
shnum = elf_getu16(swap, elfhdr.e_shnum);
65+
if (shnum > MAX_SHNUM)
66+
return toomany(ms, "section", shnum);
5867
if (doshn(ms, clazz, swap, fd,
59-
(off_t)elf_getu(swap, elfhdr.e_shoff),
60-
elf_getu16(swap, elfhdr.e_shnum),
68+
(off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
6169
(size_t)elf_getu16(swap, elfhdr.e_shentsize),
6270
fsize, &flags, elf_getu16(swap, elfhdr.e_machine),
6371
(int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1)

Diff for: src/readelf.c

+16-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include "file.h"
2828

2929
#ifndef lint
30-
FILE_RCSID("@(#)$File: readelf.c,v 1.103 2014/05/02 02:25:10 christos Exp $")
30+
FILE_RCSID("@(#)$File: readelf.c,v 1.104 2014/10/17 15:49:00 christos Exp $")
3131
#endif
3232

3333
#ifdef BUILTIN_ELF
@@ -60,6 +60,18 @@ private uint16_t getu16(int, uint16_t);
6060
private uint32_t getu32(int, uint32_t);
6161
private uint64_t getu64(int, uint64_t);
6262

63+
#define MAX_PHNUM 256
64+
#define MAX_SHNUM 1024
65+
66+
private int
67+
toomany(struct magic_set *ms, const char *name, uint16_t num)
68+
{
69+
if (file_printf(ms, ", too many %s header sections (%u)", name, num
70+
) == -1)
71+
return -1;
72+
return 0;
73+
}
74+
6375
private uint16_t
6476
getu16(int swap, uint16_t value)
6577
{
@@ -499,13 +511,13 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
499511
if (namesz & 0x80000000) {
500512
(void)file_printf(ms, ", bad note name size 0x%lx",
501513
(unsigned long)namesz);
502-
return offset;
514+
return 0;
503515
}
504516

505517
if (descsz & 0x80000000) {
506518
(void)file_printf(ms, ", bad note description size 0x%lx",
507519
(unsigned long)descsz);
508-
return offset;
520+
return 0;
509521
}
510522

511523

@@ -1240,7 +1252,7 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf,
12401252
int flags = 0;
12411253
Elf32_Ehdr elf32hdr;
12421254
Elf64_Ehdr elf64hdr;
1243-
uint16_t type;
1255+
uint16_t type, phnum, shnum;
12441256

12451257
if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
12461258
return 0;

0 commit comments

Comments
 (0)