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/libelf_xlate.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/libelf_xlate.c')
-rw-r--r-- | lib/libelf/libelf_xlate.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/lib/libelf/libelf_xlate.c b/lib/libelf/libelf_xlate.c index 362e82db7cc9..5137b2ceaf89 100644 --- a/lib/libelf/libelf_xlate.c +++ b/lib/libelf/libelf_xlate.c @@ -48,6 +48,7 @@ Elf_Data * _libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding, int elfclass, int direction) { + int byteswap; size_t cnt, dsz, fsz, msz; uintptr_t sb, se, db, de; @@ -132,12 +133,17 @@ _libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding, dst->d_type = src->d_type; dst->d_size = dsz; + byteswap = encoding != LIBELF_PRIVATE(byteorder); + if (src->d_size == 0 || - (db == sb && encoding == LIBELF_PRIVATE(byteorder) && fsz == msz)) + (db == sb && !byteswap && fsz == msz)) return (dst); /* nothing more to do */ - (_libelf_get_translator(src->d_type, direction, elfclass))(dst->d_buf, - src->d_buf, cnt, encoding != LIBELF_PRIVATE(byteorder)); + if (!(_libelf_get_translator(src->d_type, direction, elfclass)) + (dst->d_buf, dsz, src->d_buf, cnt, byteswap)) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } return (dst); } |