]> granicus.if.org Git - file/commitdiff
- use pread
authorChristos Zoulas <christos@zoulas.com>
Mon, 18 Feb 2013 15:40:59 +0000 (15:40 +0000)
committerChristos Zoulas <christos@zoulas.com>
Mon, 18 Feb 2013 15:40:59 +0000 (15:40 +0000)
- add reading of section header names to determine if an ELF file is stripped
  (Jan Kaluza)

ChangeLog
configure.ac
src/cdf.c
src/elfclass.h
src/file.h
src/pread.c [new file with mode: 0644]
src/readelf.c

index 3ea779bc55abed05bf9294a80395e28bd4151a71..9f6aab7b0cd03b535c0c5edaeac970c6bf1d3892 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2013-02-18  10:39  Christos Zoulas <christos@zoulas.com>
+
+       * add elf reading of debug info to determine if file is stripped
+         (Jan Kaluza)
+       * use pread()
+
 2013-01-25  18:05  Christos Zoulas <christos@zoulas.com>
 
        * change mime description size from 64 to 80 to accommodate OOXML.
index ac5d8c6c3df2e7e54fc403bb4ae755c126cf9979..0e0080a6fdc389910a578f630f8286ac423b97e6 100644 (file)
@@ -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)
index ba8917155000087f5b19bb39f2a0b27fe4ba1e47..6116cc62c6e96548418d7d9769d741f4e9f4fee2 100644 (file)
--- 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 <assert.h>
@@ -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;
index 2e7741b3fc00a051f4ec145918b1a5141044bd83..010958a4296fb8872a0203cc928617cb268fb6d8 100644 (file)
@@ -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;
 
index 4c0376693d0b5e2a39c230a2918c479b64c3af73..90338b2c5ec5981c95be737f725d129bb34118a0 100644 (file)
@@ -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 (file)
index 0000000..94eca15
--- /dev/null
@@ -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 <fcntl.h>
+#include <unistd.h>
+
+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);
+}
index 8212330d6b1d09c1b1a4aa4e1ae6a9a80a3c79a9..f7b00241a66a7861e4544d18bf3249924eda39df 100644 (file)
@@ -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;