aboutsummaryrefslogtreecommitdiff
path: root/lib/libelf/elf_data.c
diff options
context:
space:
mode:
authorKai Wang <kaiw@FreeBSD.org>2010-07-21 10:25:02 +0000
committerKai Wang <kaiw@FreeBSD.org>2010-07-21 10:25:02 +0000
commitf0f10541db7240f5b549bd2590c1eec9f3d17e4e (patch)
tree49e27eb10d72ea7dccf8d6dc7232254e881bb052 /lib/libelf/elf_data.c
parent4e55157fa4c135885d66cffa8ec16e988014b7cc (diff)
downloadsrc-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.c13
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);
}