Check elf section fits into memory and fail elf2b() on elf handling errors
This commit is contained in:
parent
3b30e5d424
commit
2e98ee3a1c
35
src/fileio.c
35
src/fileio.c
|
@ -772,7 +772,7 @@ static int elf2b(const char *infile, FILE *inf,
|
||||||
int bufsize, unsigned int fileoffset)
|
int bufsize, unsigned int fileoffset)
|
||||||
{
|
{
|
||||||
Elf *e;
|
Elf *e;
|
||||||
int rv = -1;
|
int rv = 0, size = 0;
|
||||||
unsigned int low, high, foff;
|
unsigned int low, high, foff;
|
||||||
|
|
||||||
if (elf_mem_limits(mem, p, &low, &high, &foff) != 0) {
|
if (elf_mem_limits(mem, p, &low, &high, &foff) != 0) {
|
||||||
|
@ -897,6 +897,7 @@ static int elf2b(const char *infile, FILE *inf,
|
||||||
|
|
||||||
if (sh == NULL) {
|
if (sh == NULL) {
|
||||||
pmsg_error("unable to read section #%u header: %s\n", (unsigned int) ndx, elf_errmsg(-1));
|
pmsg_error("unable to read section #%u header: %s\n", (unsigned int) ndx, elf_errmsg(-1));
|
||||||
|
rv = -1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Only interested in PROGBITS, ALLOC sections
|
// Only interested in PROGBITS, ALLOC sections
|
||||||
|
@ -927,8 +928,9 @@ static int elf2b(const char *infile, FILE *inf,
|
||||||
* from it, using the "foff" offset obtained above.
|
* from it, using the "foff" offset obtained above.
|
||||||
*/
|
*/
|
||||||
if (mem->size != 1 && sh->sh_size > (unsigned) mem->size) {
|
if (mem->size != 1 && sh->sh_size > (unsigned) mem->size) {
|
||||||
pmsg_error("section %s does not fit into %s memory:\n"
|
pmsg_error("section %s of size %u does not fit into %s of size %d\n",
|
||||||
" 0x%x + %u > %u\n", sname, mem->desc, lma, sh->sh_size, mem->size);
|
sname, sh->sh_size, mem->desc, mem->size);
|
||||||
|
rv = -1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -939,31 +941,38 @@ static int elf2b(const char *infile, FILE *inf,
|
||||||
if (mem->size == 1) {
|
if (mem->size == 1) {
|
||||||
if (d->d_off != 0) {
|
if (d->d_off != 0) {
|
||||||
pmsg_error("unexpected data block at offset != 0\n");
|
pmsg_error("unexpected data block at offset != 0\n");
|
||||||
|
rv = -1;
|
||||||
} else if (foff >= d->d_size) {
|
} else if (foff >= d->d_size) {
|
||||||
pmsg_error("ELF file section does not contain byte at offset %d\n", foff);
|
pmsg_error("ELF file section does not contain byte at offset %d\n", foff);
|
||||||
|
rv = -1;
|
||||||
} else {
|
} else {
|
||||||
msg_notice2(" Extracting one byte from file offset %d\n", foff);
|
msg_notice2(" Extracting one byte from file offset %d\n", foff);
|
||||||
mem->buf[0] = ((unsigned char *)d->d_buf)[foff];
|
mem->buf[0] = ((unsigned char *)d->d_buf)[foff];
|
||||||
mem->tags[0] = TAG_ALLOCATED;
|
mem->tags[0] = TAG_ALLOCATED;
|
||||||
rv = 1;
|
size = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unsigned int idx;
|
int idx = lma-low + d->d_off;
|
||||||
|
int end = idx + d->d_size;
|
||||||
|
|
||||||
idx = lma - low + d->d_off;
|
if(idx >= 0 && idx < mem->size && end >= 0 && end <= mem->size && end-idx >= 0) {
|
||||||
if ((int)(idx + d->d_size) > rv)
|
if (end > size)
|
||||||
rv = idx + d->d_size;
|
size = end;
|
||||||
msg_debug(" Writing %ld bytes to mem offset 0x%x\n",
|
imsg_debug("writing %d bytes to mem offset 0x%x\n", end-idx, idx);
|
||||||
(long) d->d_size, idx);
|
memcpy(mem->buf + idx, d->d_buf, end-idx);
|
||||||
memcpy(mem->buf + idx, d->d_buf, d->d_size);
|
memset(mem->tags + idx, TAG_ALLOCATED, end-idx);
|
||||||
memset(mem->tags + idx, TAG_ALLOCATED, d->d_size);
|
} else {
|
||||||
|
pmsg_error("section %s [0x%04x, 0x%04x] does not fit into %s [0, 0x%04x]\n",
|
||||||
|
sname, idx, (int) (idx + d->d_size-1), mem->desc, mem->size-1);
|
||||||
|
rv = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
(void)elf_end(e);
|
(void)elf_end(e);
|
||||||
return rv;
|
return rv<0? rv: size;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_LIBELF */
|
#endif /* HAVE_LIBELF */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue