From: Christos Zoulas Date: Mon, 18 Feb 2013 15:40:59 +0000 (+0000) Subject: - use pread X-Git-Tag: FILE5_13~6 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d68a455e1a8d81bc7991c7ad0f07b24697b1ff6e;p=file - use pread - add reading of section header names to determine if an ELF file is stripped (Jan Kaluza) --- diff --git a/ChangeLog b/ChangeLog index 3ea779bc..9f6aab7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-02-18 10:39 Christos Zoulas + + * add elf reading of debug info to determine if file is stripped + (Jan Kaluza) + * use pread() + 2013-01-25 18:05 Christos Zoulas * change mime description size from 64 to 80 to accommodate OOXML. diff --git a/configure.ac b/configure.ac index ac5d8c6c..0e0080a6 100644 --- a/configure.ac +++ b/configure.ac @@ -140,7 +140,7 @@ dnl Checks for functions AC_CHECK_FUNCS(strerror strndup strtoul mkstemp mkostemp utimes utime wcwidth strtof) dnl Provide implementation of some required functions if necessary -AC_REPLACE_FUNCS(getopt_long asprintf vasprintf strlcpy strlcat getline ctime_r asctime_r) +AC_REPLACE_FUNCS(getopt_long asprintf vasprintf strlcpy strlcat getline ctime_r asctime_r pread) dnl Checks for libraries AC_CHECK_LIB(z,gzopen) diff --git a/src/cdf.c b/src/cdf.c index ba891715..6116cc62 100644 --- a/src/cdf.c +++ b/src/cdf.c @@ -35,7 +35,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: cdf.c,v 1.50 2012/02/20 22:35:29 christos Exp $") +FILE_RCSID("@(#)$File: cdf.c,v 1.51 2012/03/20 18:28:02 christos Exp $") #endif #include @@ -296,10 +296,9 @@ cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len) if (info->i_fd == -1) return -1; - if (lseek(info->i_fd, off, SEEK_SET) == (off_t)-1) return -1; - if (read(info->i_fd, buf, len) != (ssize_t)len) + if (pread(info->i_fd, buf, len, off) != (ssize_t)len) return -1; return (ssize_t)len; diff --git a/src/elfclass.h b/src/elfclass.h index 2e7741b3..010958a4 100644 --- a/src/elfclass.h +++ b/src/elfclass.h @@ -59,7 +59,8 @@ (off_t)elf_getu(swap, elfhdr.e_shoff), elf_getu16(swap, elfhdr.e_shnum), (size_t)elf_getu16(swap, elfhdr.e_shentsize), - fsize, &flags, elf_getu16(swap, elfhdr.e_machine)) == -1) + fsize, &flags, elf_getu16(swap, elfhdr.e_machine), + (int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1) return -1; break; diff --git a/src/file.h b/src/file.h index 4c037669..90338b2c 100644 --- a/src/file.h +++ b/src/file.h @@ -27,7 +27,7 @@ */ /* * file.h - definitions for file(1) program - * @(#)$File: file.h,v 1.142 2013/01/07 18:06:40 christos Exp $ + * @(#)$File: file.h,v 1.143 2013/01/25 23:07:19 christos Exp $ */ #ifndef __file_h__ @@ -484,6 +484,9 @@ extern char *sys_errlist[]; #define strtoul(a, b, c) strtol(a, b, c) #endif +#ifndef HAVE_PREAD +ssize_t pread(int, void *, size_t, off_t); +#endif #ifndef HAVE_VASPRINTF int vasprintf(char **, const char *, va_list); #endif diff --git a/src/pread.c b/src/pread.c new file mode 100644 index 00000000..94eca15d --- /dev/null +++ b/src/pread.c @@ -0,0 +1,14 @@ +#include "file.h" +#ifndef lint +FILE_RCSID("@(#)$File: ctime_r.c,v 1.1 2012/05/15 17:14:36 christos Exp $") +#endif /* lint */ +#include +#include + +ssize_t +pread(int fd, void *buf, ssize_t len, off_t off) { + if (lseek(fd, off, SEEK_SET) == (off_t)-1) + return -1; + + return read(fd, buf, len); +} diff --git a/src/readelf.c b/src/readelf.c index 8212330d..f7b00241 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: readelf.c,v 1.93 2012/10/31 17:03:41 christos Exp $") +FILE_RCSID("@(#)$File: readelf.c,v 1.94 2012/12/13 13:48:31 christos Exp $") #endif #ifdef BUILTIN_ELF @@ -48,7 +48,7 @@ private int dophn_core(struct magic_set *, int, int, int, off_t, int, size_t, private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t, off_t, int *, int); private int doshn(struct magic_set *, int, int, int, off_t, int, size_t, - off_t, int *, int); + off_t, int *, int, int); private size_t donote(struct magic_set *, void *, size_t, size_t, int, int, size_t, int *); @@ -133,19 +133,21 @@ getu64(int swap, uint64_t value) #define elf_getu32(swap, value) getu32(swap, value) #ifdef USE_ARRAY_FOR_64BIT_TYPES # define elf_getu64(swap, array) \ - ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 : elf_getu32(swap, array[0])) + \ - (swap ? elf_getu32(swap, array[1]) : ((uint64_t)elf_getu32(swap, array[1]) << 32))) + ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 \ + : elf_getu32(swap, array[0])) + \ + (swap ? elf_getu32(swap, array[1]) : \ + ((uint64_t)elf_getu32(swap, array[1]) << 32))) #else # define elf_getu64(swap, value) getu64(swap, value) #endif #define xsh_addr (clazz == ELFCLASS32 \ - ? (void *) &sh32 \ - : (void *) &sh64) + ? (void *)&sh32 \ + : (void *)&sh64) #define xsh_sizeof (clazz == ELFCLASS32 \ - ? sizeof sh32 \ - : sizeof sh64) -#define xsh_size (clazz == ELFCLASS32 \ + ? sizeof(sh32) \ + : sizeof(sh64)) +#define xsh_size (size_t)(clazz == ELFCLASS32 \ ? elf_getu32(swap, sh32.sh_size) \ : elf_getu64(swap, sh64.sh_size)) #define xsh_offset (off_t)(clazz == ELFCLASS32 \ @@ -154,12 +156,15 @@ getu64(int swap, uint64_t value) #define xsh_type (clazz == ELFCLASS32 \ ? elf_getu32(swap, sh32.sh_type) \ : elf_getu32(swap, sh64.sh_type)) +#define xsh_name (clazz == ELFCLASS32 \ + ? elf_getu32(swap, sh32.sh_name) \ + : elf_getu32(swap, sh64.sh_name)) #define xph_addr (clazz == ELFCLASS32 \ ? (void *) &ph32 \ : (void *) &ph64) #define xph_sizeof (clazz == ELFCLASS32 \ - ? sizeof ph32 \ - : sizeof ph64) + ? sizeof(ph32) \ + : sizeof(ph64)) #define xph_type (clazz == ELFCLASS32 \ ? elf_getu32(swap, ph32.p_type) \ : elf_getu32(swap, ph64.p_type)) @@ -175,8 +180,8 @@ getu64(int swap, uint64_t value) ? elf_getu32(swap, ph32.p_filesz) \ : elf_getu64(swap, ph64.p_filesz))) #define xnh_addr (clazz == ELFCLASS32 \ - ? (void *) &nh32 \ - : (void *) &nh64) + ? (void *)&nh32 \ + : (void *)&nh64) #define xph_memsz (size_t)((clazz == ELFCLASS32 \ ? elf_getu32(swap, ph32.p_memsz) \ : elf_getu64(swap, ph64.p_memsz))) @@ -196,8 +201,8 @@ getu64(int swap, uint64_t value) ? prpsoffsets32[i] \ : prpsoffsets64[i]) #define xcap_addr (clazz == ELFCLASS32 \ - ? (void *) &cap32 \ - : (void *) &cap64) + ? (void *)&cap32 \ + : (void *)&cap64) #define xcap_sizeof (clazz == ELFCLASS32 \ ? sizeof cap32 \ : sizeof cap64) @@ -299,7 +304,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, { Elf32_Phdr ph32; Elf64_Phdr ph64; - size_t offset; + size_t offset, len; unsigned char nbuf[BUFSIZ]; ssize_t bufsize; @@ -313,11 +318,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, * Loop through all the program headers. */ for ( ; num; num--) { - if (lseek(fd, off, SEEK_SET) == (off_t)-1) { - file_badseek(ms); - return -1; - } - if (read(fd, xph_addr, xph_sizeof) == -1) { + if (pread(fd, xph_addr, xph_sizeof, off) == -1) { file_badread(ms); return -1; } @@ -335,13 +336,8 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, * This is a PT_NOTE section; loop through all the notes * in the section. */ - if (lseek(fd, xph_offset, SEEK_SET) == (off_t)-1) { - file_badseek(ms); - return -1; - } - bufsize = read(fd, nbuf, - ((xph_filesz < sizeof(nbuf)) ? xph_filesz : sizeof(nbuf))); - if (bufsize == -1) { + len = xph_filesz < sizeof(nbuf) ? xph_filesz : sizeof(nbuf); + if ((bufsize = pread(fd, nbuf, len, xph_offset)) == -1) { file_badread(ms); return -1; } @@ -851,15 +847,16 @@ static const cap_desc_t cap_desc_386[] = { private int doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, - size_t size, off_t fsize, int *flags, int mach) + size_t size, off_t fsize, int *flags, int mach, int strtab) { Elf32_Shdr sh32; Elf64_Shdr sh64; int stripped = 1; void *nbuf; - off_t noff, coff; + off_t noff, coff, name_off; uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */ uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */ + char name[50]; if (size != xsh_sizeof) { if (file_printf(ms, ", corrupted section header size") == -1) @@ -867,12 +864,19 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, return 0; } + /* Save offset of name section to be able to read section names later */ + name_off = off * size * strtab; + /* Read the name of this section. */ + if (pread(fd, name, sizeof(name), name_off + xsh_name) == -1) { + file_badread(ms); + return -1; + } + name[sizeof(name) - 1] = '\0'; + if (strcmp(name, ".debug_info") == 0) + stripped = 0; + for ( ; num; num--) { - if (lseek(fd, off, SEEK_SET) == (off_t)-1) { - file_badseek(ms); - return -1; - } - if (read(fd, xsh_addr, xsh_sizeof) == -1) { + if (pread(fd, xsh_addr, xsh_sizeof, off) == -1) { file_badread(ms); return -1; } @@ -897,31 +901,23 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, /* Things we can determine when we seek */ switch (xsh_type) { case SHT_NOTE: - if ((nbuf = malloc((size_t)xsh_size)) == NULL) { + if ((nbuf = malloc(xsh_size)) == NULL) { file_error(ms, errno, "Cannot allocate memory" " for note"); return -1; } - if ((noff = lseek(fd, (off_t)xsh_offset, SEEK_SET)) == - (off_t)-1) { + if (pread(fd, nbuf, xsh_size, xsh_offset) == -1) { file_badread(ms); free(nbuf); return -1; } - if (read(fd, nbuf, (size_t)xsh_size) != - (ssize_t)xsh_size) { - free(nbuf); - file_badread(ms); - return -1; - } noff = 0; for (;;) { if (noff >= (off_t)xsh_size) break; noff = donote(ms, nbuf, (size_t)noff, - (size_t)xsh_size, clazz, swap, 4, - flags); + xsh_size, clazz, swap, 4, flags); if (noff == 0) break; } @@ -939,8 +935,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, goto skip; } - if (lseek(fd, (off_t)xsh_offset, SEEK_SET) == - (off_t)-1) { + if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) { file_badseek(ms); return -1; } @@ -1063,7 +1058,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, const char *shared_libraries = ""; unsigned char nbuf[BUFSIZ]; ssize_t bufsize; - size_t offset, align; + size_t offset, align, len; if (size != xph_sizeof) { if (file_printf(ms, ", corrupted program header size") == -1) @@ -1072,13 +1067,8 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, } for ( ; num; num--) { - if (lseek(fd, off, SEEK_SET) == (off_t)-1) { - file_badseek(ms); - return -1; - } - - if (read(fd, xph_addr, xph_sizeof) == -1) { - file_badread(ms); + if (pread(fd, xph_addr, xph_sizeof, off) == -1) { + file_badread(ms); return -1; } @@ -1116,12 +1106,9 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, * This is a PT_NOTE section; loop through all the notes * in the section. */ - if (lseek(fd, xph_offset, SEEK_SET) == (off_t)-1) { - file_badseek(ms); - return -1; - } - bufsize = read(fd, nbuf, ((xph_filesz < sizeof(nbuf)) ? - xph_filesz : sizeof(nbuf))); + len = xph_filesz < sizeof(nbuf) ? xph_filesz + : sizeof(nbuf); + bufsize = pread(fd, nbuf, len, xph_offset); if (bufsize == -1) { file_badread(ms); return -1;