diff options
Diffstat (limited to 'rtemstoolkit/elftoolchain/libelf/libelf_ar.c')
-rw-r--r-- | rtemstoolkit/elftoolchain/libelf/libelf_ar.c | 53 |
1 files changed, 29 insertions, 24 deletions
diff --git a/rtemstoolkit/elftoolchain/libelf/libelf_ar.c b/rtemstoolkit/elftoolchain/libelf/libelf_ar.c index 14b383d..8fce741 100644 --- a/rtemstoolkit/elftoolchain/libelf/libelf_ar.c +++ b/rtemstoolkit/elftoolchain/libelf/libelf_ar.c @@ -24,8 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> - #include <assert.h> #include <ctype.h> #include <libelf.h> @@ -35,7 +33,7 @@ #include "_libelf.h" #include "_libelf_ar.h" -LIBELF_VCSID("$Id: libelf_ar.c 1341 2011-01-01 04:28:29Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_ar.c 3446 2016-05-03 01:31:17Z emaste $"); #define LIBELF_NALLOC_SIZE 16 @@ -66,7 +64,7 @@ LIBELF_VCSID("$Id: libelf_ar.c 1341 2011-01-01 04:28:29Z jkoshy $"); * table where the actual file name of the object starts. Strings in * the string table are padded to start on even addresses. * - * In the BSD format, file names can be upto 16 characters. File + * In the BSD format, file names can be up to 16 characters. File * names shorter than 16 characters are padded to 16 characters using * (ASCII) space characters. File names with embedded spaces and file * names longer than 16 characters are stored immediately after the @@ -110,8 +108,8 @@ Elf_Arhdr * _libelf_ar_gethdr(Elf *e) { Elf *parent; - char *namelen; Elf_Arhdr *eh; + char *namelen; size_t n, nlen; struct ar_hdr *arh; @@ -192,7 +190,7 @@ _libelf_ar_gethdr(Elf *e) } e->e_flags &= ~LIBELF_F_AR_HEADER; - e->e_hdr.e_rawhdr = (char *) arh; + e->e_hdr.e_rawhdr = (unsigned char *) arh; return (NULL); } @@ -201,10 +199,10 @@ Elf * _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) { Elf *e; - char *member, *namelen; - size_t nsz, sz; off_t next; + size_t nsz, sz; struct ar_hdr *arh; + char *member, *namelen; assert(elf->e_kind == ELF_K_AR); @@ -249,12 +247,12 @@ _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) member = (char *) (arh + 1); - if ((e = elf_memory((char *) member, sz)) == NULL) + if ((e = elf_memory(member, sz)) == NULL) return (NULL); e->e_fd = fd; e->e_cmd = c; - e->e_hdr.e_rawhdr = (char *) arh; + e->e_hdr.e_rawhdr = (unsigned char *) arh; elf->e_u.e_ar.e_nchildren++; e->e_parent = elf; @@ -274,9 +272,10 @@ _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) */ /* - * A helper macro to read in a 'long' value from the archive. We use - * memcpy() since the source pointer may be misaligned with respect to - * the natural alignment for a C 'long'. + * A helper macro to read in a 'long' value from the archive. + * + * We use memcpy() since the source pointer may be misaligned with + * respect to the natural alignment for a C 'long'. */ #define GET_LONG(P, V)do { \ memcpy(&(V), (P), sizeof(long)); \ @@ -287,9 +286,10 @@ Elf_Arsym * _libelf_ar_process_bsd_symtab(Elf *e, size_t *count) { Elf_Arsym *symtab, *sym; + unsigned int n, nentries; unsigned char *end, *p, *p0, *s, *s0; - const unsigned int entrysize = 2 * sizeof(long); - long arraysize, fileoffset, n, nentries, stroffset, strtabsize; + const size_t entrysize = 2 * sizeof(long); + long arraysize, fileoffset, stroffset, strtabsize; assert(e != NULL); assert(count != NULL); @@ -313,7 +313,8 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count) */ GET_LONG(p, arraysize); - if (p0 + arraysize >= end || (arraysize % entrysize != 0)) + if (arraysize < 0 || p0 + arraysize >= end || + ((size_t) arraysize % entrysize != 0)) goto symtaberror; /* @@ -323,10 +324,10 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count) GET_LONG(s, strtabsize); s0 = s; /* Start of string table. */ - if (s0 + strtabsize > end) + if (strtabsize < 0 || s0 + strtabsize > end) goto symtaberror; - nentries = arraysize / entrysize; + nentries = (size_t) arraysize / entrysize; /* * Allocate space for the returned Elf_Arsym array. @@ -341,12 +342,16 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count) GET_LONG(p, stroffset); GET_LONG(p, fileoffset); + if (stroffset < 0 || fileoffset < 0 || + (size_t) fileoffset >= e->e_rawsize) + goto symtaberror; + s = s0 + stroffset; if (s >= end) goto symtaberror; - sym->as_off = fileoffset; + sym->as_off = (off_t) fileoffset; sym->as_hash = elf_hash((char *) s); sym->as_name = (char *) s; } @@ -393,7 +398,8 @@ symtaberror: Elf_Arsym * _libelf_ar_process_svr4_symtab(Elf *e, size_t *count) { - size_t n, nentries, off; + uint32_t off; + size_t n, nentries; Elf_Arsym *symtab, *sym; unsigned char *p, *s, *end; @@ -424,15 +430,14 @@ _libelf_ar_process_svr4_symtab(Elf *e, size_t *count) s = p + (nentries * INTSZ); /* start of the string table. */ for (n = nentries, sym = symtab; n > 0; n--) { - if (s >= end) goto symtaberror; - off = 0; - GET_WORD(p, off); + if (off >= e->e_rawsize) + goto symtaberror; - sym->as_off = off; + sym->as_off = (off_t) off; sym->as_hash = elf_hash((char *) s); sym->as_name = (char *) s; |