diff options
author | Kai Wang <kaiw@FreeBSD.org> | 2010-07-21 10:25:02 +0000 |
---|---|---|
committer | Kai Wang <kaiw@FreeBSD.org> | 2010-07-21 10:25:02 +0000 |
commit | f0f10541db7240f5b549bd2590c1eec9f3d17e4e (patch) | |
tree | 49e27eb10d72ea7dccf8d6dc7232254e881bb052 /lib/libelf/elf_data.c | |
parent | 4e55157fa4c135885d66cffa8ec16e988014b7cc (diff) | |
download | src-f0f10541db7240f5b549bd2590c1eec9f3d17e4e.tar.gz src-f0f10541db7240f5b549bd2590c1eec9f3d17e4e.zip |
Perform additional checks when translating between file and memory
representations of ELF types.
The ELF(3) API allows applications to request a conversion that is
`in-place', i.e., with source and destinations data buffers being
the same. However, the file and memory sizes of ELF sections that
have additional internal structure, such as those of type `Elf_Note',
or `Elf_GNU_Hash_Header', can be determined only known after the
type-specific headers that comprise the first few words in these
sections are read and translated.
Pass in the size of destination buffer to type translation routines
in "libelf_convert.m4" and have these routines return an error code
if the translated data would not fit inside the destination buffer.
Obtained from: elftoolchain
MFC after: 1 month
Notes
Notes:
svn path=/head/; revision=210338
Diffstat (limited to 'lib/libelf/elf_data.c')
-rw-r--r-- | lib/libelf/elf_data.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/lib/libelf/elf_data.c b/lib/libelf/elf_data.c index 0fbbae0087c8..9241b09dce18 100644 --- a/lib/libelf/elf_data.c +++ b/lib/libelf/elf_data.c @@ -43,7 +43,7 @@ elf_getdata(Elf_Scn *s, Elf_Data *d) int elfclass, elftype; unsigned int sh_type; uint64_t sh_align, sh_offset, sh_size; - void (*xlate)(char *_d, char *_s, size_t _c, int _swap); + int (*xlate)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); if (s == NULL || (e = s->s_elf) == NULL || e->e_kind != ELF_K_ELF || (d != NULL && s != d->d_scn)) { @@ -125,11 +125,16 @@ elf_getdata(Elf_Scn *s, Elf_Data *d) } d->d_flags |= LIBELF_F_MALLOCED; - STAILQ_INSERT_TAIL(&s->s_data, d, d_next); xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass); - (*xlate)(d->d_buf, e->e_rawfile + sh_offset, count, e->e_byteorder != - LIBELF_PRIVATE(byteorder)); + if (!(*xlate)(d->d_buf, d->d_size, e->e_rawfile + sh_offset, count, + e->e_byteorder != LIBELF_PRIVATE(byteorder))) { + _libelf_release_data(d); + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + STAILQ_INSERT_TAIL(&s->s_data, d, d_next); return (d); } |