|
|
89be67 |
diff --git a/configure.ac b/configure.ac
|
|
|
89be67 |
index 1511c9a..97a4689 100644
|
|
|
89be67 |
--- a/configure.ac
|
|
|
89be67 |
+++ b/configure.ac
|
|
|
89be67 |
@@ -159,7 +159,7 @@ dnl Checks for functions
|
|
|
89be67 |
AC_CHECK_FUNCS(mmap strerror strndup strtoul mbrtowc mkstemp utimes utime wcwidth strtof fork)
|
|
|
89be67 |
|
|
|
89be67 |
dnl Provide implementation of some required functions if necessary
|
|
|
89be67 |
-AC_REPLACE_FUNCS(getopt_long asprintf vasprintf strlcpy strlcat getline)
|
|
|
89be67 |
+AC_REPLACE_FUNCS(getopt_long asprintf vasprintf strlcpy strlcat getline pread)
|
|
|
89be67 |
|
|
|
89be67 |
dnl Checks for libraries
|
|
|
89be67 |
AC_CHECK_LIB(z,gzopen)
|
|
|
89be67 |
diff --git a/src/cdf.c b/src/cdf.c
|
|
|
89be67 |
index d05d279..3b2b79b 100644
|
|
|
89be67 |
--- a/src/cdf.c
|
|
|
89be67 |
+++ b/src/cdf.c
|
|
|
89be67 |
@@ -35,7 +35,7 @@
|
|
|
89be67 |
#include "file.h"
|
|
|
89be67 |
|
|
|
89be67 |
#ifndef lint
|
|
|
89be67 |
-FILE_RCSID("@(#)$File: cdf.c,v 1.50 2012/02/20 22:35:29 christos Exp $")
|
|
|
89be67 |
+FILE_RCSID("@(#)$File: cdf.c,v 1.51 2012/03/20 18:28:02 christos Exp $")
|
|
|
89be67 |
#endif
|
|
|
89be67 |
|
|
|
89be67 |
#include <assert.h>
|
|
|
89be67 |
@@ -296,10 +296,7 @@ cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len)
|
|
|
89be67 |
if (info->i_fd == -1)
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
|
|
|
89be67 |
- if (lseek(info->i_fd, off, SEEK_SET) == (off_t)-1)
|
|
|
89be67 |
- return -1;
|
|
|
89be67 |
-
|
|
|
89be67 |
- if (read(info->i_fd, buf, len) != (ssize_t)len)
|
|
|
89be67 |
+ if (pread(info->i_fd, buf, len, off) != (ssize_t)len)
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
|
|
|
89be67 |
return (ssize_t)len;
|
|
|
89be67 |
diff --git a/src/elfclass.h b/src/elfclass.h
|
|
|
89be67 |
index 2e7741b..010958a 100644
|
|
|
89be67 |
--- a/src/elfclass.h
|
|
|
89be67 |
+++ b/src/elfclass.h
|
|
|
89be67 |
@@ -59,7 +59,8 @@
|
|
|
89be67 |
(off_t)elf_getu(swap, elfhdr.e_shoff),
|
|
|
89be67 |
elf_getu16(swap, elfhdr.e_shnum),
|
|
|
89be67 |
(size_t)elf_getu16(swap, elfhdr.e_shentsize),
|
|
|
89be67 |
- fsize, &flags, elf_getu16(swap, elfhdr.e_machine)) == -1)
|
|
|
89be67 |
+ fsize, &flags, elf_getu16(swap, elfhdr.e_machine),
|
|
|
89be67 |
+ (int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1)
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
break;
|
|
|
89be67 |
|
|
|
89be67 |
diff --git a/src/file.h b/src/file.h
|
|
|
89be67 |
index 1b5f53f..28f9bc7 100644
|
|
|
89be67 |
--- a/src/file.h
|
|
|
89be67 |
+++ b/src/file.h
|
|
|
89be67 |
@@ -462,6 +462,9 @@ extern char *sys_errlist[];
|
|
|
89be67 |
#define strtoul(a, b, c) strtol(a, b, c)
|
|
|
89be67 |
#endif
|
|
|
89be67 |
|
|
|
89be67 |
+#ifndef HAVE_PREAD
|
|
|
89be67 |
+ssize_t pread(int, void *, size_t, off_t);
|
|
|
89be67 |
+#endif
|
|
|
89be67 |
#ifndef HAVE_VASPRINTF
|
|
|
89be67 |
int vasprintf(char **, const char *, va_list);
|
|
|
89be67 |
#endif
|
|
|
89be67 |
diff --git a/src/readelf.c b/src/readelf.c
|
|
|
89be67 |
index ce4832a..8d355c5 100644
|
|
|
89be67 |
--- a/src/readelf.c
|
|
|
89be67 |
+++ b/src/readelf.c
|
|
|
89be67 |
@@ -48,7 +48,7 @@ private int dophn_core(struct magic_set *, int, int, int, off_t, int, size_t,
|
|
|
89be67 |
private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t,
|
|
|
89be67 |
off_t, int *, int);
|
|
|
89be67 |
private int doshn(struct magic_set *, int, int, int, off_t, int, size_t,
|
|
|
89be67 |
- off_t, int *, int);
|
|
|
89be67 |
+ off_t, int *, int, int);
|
|
|
89be67 |
private size_t donote(struct magic_set *, void *, size_t, size_t, int,
|
|
|
89be67 |
int, size_t, int *);
|
|
|
89be67 |
|
|
|
89be67 |
@@ -129,19 +129,21 @@ getu64(int swap, uint64_t value)
|
|
|
89be67 |
#define elf_getu32(swap, value) getu32(swap, value)
|
|
|
89be67 |
#ifdef USE_ARRAY_FOR_64BIT_TYPES
|
|
|
89be67 |
# define elf_getu64(swap, array) \
|
|
|
89be67 |
- ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 : elf_getu32(swap, array[0])) + \
|
|
|
89be67 |
- (swap ? elf_getu32(swap, array[1]) : ((uint64_t)elf_getu32(swap, array[1]) << 32)))
|
|
|
89be67 |
+ ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 \
|
|
|
89be67 |
+ : elf_getu32(swap, array[0])) + \
|
|
|
89be67 |
+ (swap ? elf_getu32(swap, array[1]) : \
|
|
|
89be67 |
+ ((uint64_t)elf_getu32(swap, array[1]) << 32)))
|
|
|
89be67 |
#else
|
|
|
89be67 |
# define elf_getu64(swap, value) getu64(swap, value)
|
|
|
89be67 |
#endif
|
|
|
89be67 |
|
|
|
89be67 |
#define xsh_addr (clazz == ELFCLASS32 \
|
|
|
89be67 |
- ? (void *) &sh32 \
|
|
|
89be67 |
- : (void *) &sh64)
|
|
|
89be67 |
+ ? (void *)&sh32 \
|
|
|
89be67 |
+ : (void *)&sh64)
|
|
|
89be67 |
#define xsh_sizeof (clazz == ELFCLASS32 \
|
|
|
89be67 |
- ? sizeof sh32 \
|
|
|
89be67 |
- : sizeof sh64)
|
|
|
89be67 |
-#define xsh_size (clazz == ELFCLASS32 \
|
|
|
89be67 |
+ ? sizeof(sh32) \
|
|
|
89be67 |
+ : sizeof(sh64))
|
|
|
89be67 |
+#define xsh_size (size_t)(clazz == ELFCLASS32 \
|
|
|
89be67 |
? elf_getu32(swap, sh32.sh_size) \
|
|
|
89be67 |
: elf_getu64(swap, sh64.sh_size))
|
|
|
89be67 |
#define xsh_offset (off_t)(clazz == ELFCLASS32 \
|
|
|
89be67 |
@@ -150,12 +152,15 @@ getu64(int swap, uint64_t value)
|
|
|
89be67 |
#define xsh_type (clazz == ELFCLASS32 \
|
|
|
89be67 |
? elf_getu32(swap, sh32.sh_type) \
|
|
|
89be67 |
: elf_getu32(swap, sh64.sh_type))
|
|
|
89be67 |
+#define xsh_name (clazz == ELFCLASS32 \
|
|
|
89be67 |
+ ? elf_getu32(swap, sh32.sh_name) \
|
|
|
89be67 |
+ : elf_getu32(swap, sh64.sh_name))
|
|
|
89be67 |
#define xph_addr (clazz == ELFCLASS32 \
|
|
|
89be67 |
? (void *) &ph32 \
|
|
|
89be67 |
: (void *) &ph64)
|
|
|
89be67 |
#define xph_sizeof (clazz == ELFCLASS32 \
|
|
|
89be67 |
- ? sizeof ph32 \
|
|
|
89be67 |
- : sizeof ph64)
|
|
|
89be67 |
+ ? sizeof(ph32) \
|
|
|
89be67 |
+ : sizeof(ph64))
|
|
|
89be67 |
#define xph_type (clazz == ELFCLASS32 \
|
|
|
89be67 |
? elf_getu32(swap, ph32.p_type) \
|
|
|
89be67 |
: elf_getu32(swap, ph64.p_type))
|
|
|
89be67 |
@@ -171,8 +176,8 @@ getu64(int swap, uint64_t value)
|
|
|
89be67 |
? elf_getu32(swap, ph32.p_filesz) \
|
|
|
89be67 |
: elf_getu64(swap, ph64.p_filesz)))
|
|
|
89be67 |
#define xnh_addr (clazz == ELFCLASS32 \
|
|
|
89be67 |
- ? (void *) &nh32 \
|
|
|
89be67 |
- : (void *) &nh64)
|
|
|
89be67 |
+ ? (void *)&nh32 \
|
|
|
89be67 |
+ : (void *)&nh64)
|
|
|
89be67 |
#define xph_memsz (size_t)((clazz == ELFCLASS32 \
|
|
|
89be67 |
? elf_getu32(swap, ph32.p_memsz) \
|
|
|
89be67 |
: elf_getu64(swap, ph64.p_memsz)))
|
|
|
89be67 |
@@ -192,8 +197,8 @@ getu64(int swap, uint64_t value)
|
|
|
89be67 |
? prpsoffsets32[i] \
|
|
|
89be67 |
: prpsoffsets64[i])
|
|
|
89be67 |
#define xcap_addr (clazz == ELFCLASS32 \
|
|
|
89be67 |
- ? (void *) &cap32 \
|
|
|
89be67 |
- : (void *) &cap64)
|
|
|
89be67 |
+ ? (void *)&cap32 \
|
|
|
89be67 |
+ : (void *)&cap64)
|
|
|
89be67 |
#define xcap_sizeof (clazz == ELFCLASS32 \
|
|
|
89be67 |
? sizeof cap32 \
|
|
|
89be67 |
: sizeof cap64)
|
|
|
89be67 |
@@ -296,7 +301,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
|
|
|
89be67 |
{
|
|
|
89be67 |
Elf32_Phdr ph32;
|
|
|
89be67 |
Elf64_Phdr ph64;
|
|
|
89be67 |
- size_t offset;
|
|
|
89be67 |
+ size_t offset, len;
|
|
|
89be67 |
unsigned char nbuf[BUFSIZ];
|
|
|
89be67 |
ssize_t bufsize;
|
|
|
89be67 |
|
|
|
89be67 |
@@ -310,11 +315,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
|
|
|
89be67 |
* Loop through all the program headers.
|
|
|
89be67 |
*/
|
|
|
89be67 |
for ( ; num; num--) {
|
|
|
89be67 |
- if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
|
|
|
89be67 |
- file_badseek(ms);
|
|
|
89be67 |
- return -1;
|
|
|
89be67 |
- }
|
|
|
89be67 |
- if (read(fd, xph_addr, xph_sizeof) == -1) {
|
|
|
89be67 |
+ if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
|
|
|
89be67 |
file_badread(ms);
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
}
|
|
|
89be67 |
@@ -332,13 +333,8 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
|
|
|
89be67 |
* This is a PT_NOTE section; loop through all the notes
|
|
|
89be67 |
* in the section.
|
|
|
89be67 |
*/
|
|
|
89be67 |
- if (lseek(fd, xph_offset, SEEK_SET) == (off_t)-1) {
|
|
|
89be67 |
- file_badseek(ms);
|
|
|
89be67 |
- return -1;
|
|
|
89be67 |
- }
|
|
|
89be67 |
- bufsize = read(fd, nbuf,
|
|
|
89be67 |
- ((xph_filesz < sizeof(nbuf)) ? xph_filesz : sizeof(nbuf)));
|
|
|
89be67 |
- if (bufsize == -1) {
|
|
|
89be67 |
+ len = xph_filesz < sizeof(nbuf) ? xph_filesz : sizeof(nbuf);
|
|
|
89be67 |
+ if ((bufsize = pread(fd, nbuf, len, xph_offset)) == -1) {
|
|
|
89be67 |
file_badread(ms);
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
}
|
|
|
89be67 |
@@ -843,15 +839,16 @@ static const cap_desc_t cap_desc_386[] = {
|
|
|
89be67 |
|
|
|
89be67 |
private int
|
|
|
89be67 |
doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
|
|
|
89be67 |
- size_t size, off_t fsize, int *flags, int mach)
|
|
|
89be67 |
+ size_t size, off_t fsize, int *flags, int mach, int strtab)
|
|
|
89be67 |
{
|
|
|
89be67 |
Elf32_Shdr sh32;
|
|
|
89be67 |
Elf64_Shdr sh64;
|
|
|
89be67 |
int stripped = 1;
|
|
|
89be67 |
void *nbuf;
|
|
|
89be67 |
- off_t noff, coff;
|
|
|
89be67 |
+ off_t noff, coff, name_off;
|
|
|
89be67 |
uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
|
|
|
89be67 |
uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */
|
|
|
89be67 |
+ char name[50];
|
|
|
89be67 |
|
|
|
89be67 |
if (size != xsh_sizeof) {
|
|
|
89be67 |
if (file_printf(ms, ", corrupted section header size") == -1)
|
|
|
89be67 |
@@ -859,12 +856,24 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
|
|
|
89be67 |
return 0;
|
|
|
89be67 |
}
|
|
|
89be67 |
|
|
|
89be67 |
+ /* Read offset of name section to be able to read section names later */
|
|
|
89be67 |
+ if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) == -1) {
|
|
|
89be67 |
+ file_badread(ms);
|
|
|
89be67 |
+ return -1;
|
|
|
89be67 |
+ }
|
|
|
89be67 |
+ name_off = xsh_offset;
|
|
|
89be67 |
+
|
|
|
89be67 |
for ( ; num; num--) {
|
|
|
89be67 |
- if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
|
|
|
89be67 |
- file_badseek(ms);
|
|
|
89be67 |
+ /* Read the name of this section. */
|
|
|
89be67 |
+ if (pread(fd, name, sizeof(name), name_off + xsh_name) == -1) {
|
|
|
89be67 |
+ file_badread(ms);
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
}
|
|
|
89be67 |
- if (read(fd, xsh_addr, xsh_sizeof) == -1) {
|
|
|
89be67 |
+ name[sizeof(name) - 1] = '\0';
|
|
|
89be67 |
+ if (strcmp(name, ".debug_info") == 0)
|
|
|
89be67 |
+ stripped = 0;
|
|
|
89be67 |
+
|
|
|
89be67 |
+ if (pread(fd, xsh_addr, xsh_sizeof, off) == -1) {
|
|
|
89be67 |
file_badread(ms);
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
}
|
|
|
89be67 |
@@ -889,39 +898,30 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
|
|
|
89be67 |
/* Things we can determine when we seek */
|
|
|
89be67 |
switch (xsh_type) {
|
|
|
89be67 |
case SHT_NOTE:
|
|
|
89be67 |
- if ((nbuf = malloc((size_t)xsh_size)) == NULL) {
|
|
|
89be67 |
+ if ((nbuf = malloc(xsh_size)) == NULL) {
|
|
|
89be67 |
file_error(ms, errno, "Cannot allocate memory"
|
|
|
89be67 |
" for note");
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
}
|
|
|
89be67 |
- if ((noff = lseek(fd, (off_t)xsh_offset, SEEK_SET)) ==
|
|
|
89be67 |
- (off_t)-1) {
|
|
|
89be67 |
+ if (pread(fd, nbuf, xsh_size, xsh_offset) == -1) {
|
|
|
89be67 |
file_badread(ms);
|
|
|
89be67 |
free(nbuf);
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
}
|
|
|
89be67 |
- if (read(fd, nbuf, (size_t)xsh_size) !=
|
|
|
89be67 |
- (ssize_t)xsh_size) {
|
|
|
89be67 |
- free(nbuf);
|
|
|
89be67 |
- file_badread(ms);
|
|
|
89be67 |
- return -1;
|
|
|
89be67 |
- }
|
|
|
89be67 |
|
|
|
89be67 |
noff = 0;
|
|
|
89be67 |
for (;;) {
|
|
|
89be67 |
if (noff >= (off_t)xsh_size)
|
|
|
89be67 |
break;
|
|
|
89be67 |
noff = donote(ms, nbuf, (size_t)noff,
|
|
|
89be67 |
- (size_t)xsh_size, clazz, swap, 4,
|
|
|
89be67 |
- flags);
|
|
|
89be67 |
+ xsh_size, clazz, swap, 4, flags);
|
|
|
89be67 |
if (noff == 0)
|
|
|
89be67 |
break;
|
|
|
89be67 |
}
|
|
|
89be67 |
free(nbuf);
|
|
|
89be67 |
break;
|
|
|
89be67 |
case SHT_SUNW_cap:
|
|
|
89be67 |
- if (lseek(fd, (off_t)xsh_offset, SEEK_SET) ==
|
|
|
89be67 |
- (off_t)-1) {
|
|
|
89be67 |
+ if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) {
|
|
|
89be67 |
file_badseek(ms);
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
}
|
|
|
89be67 |
@@ -1043,7 +1043,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
|
|
|
89be67 |
const char *shared_libraries = "";
|
|
|
89be67 |
unsigned char nbuf[BUFSIZ];
|
|
|
89be67 |
ssize_t bufsize;
|
|
|
89be67 |
- size_t offset, align;
|
|
|
89be67 |
+ size_t offset, align, len;
|
|
|
89be67 |
|
|
|
89be67 |
if (size != xph_sizeof) {
|
|
|
89be67 |
if (file_printf(ms, ", corrupted program header size") == -1)
|
|
|
89be67 |
@@ -1052,13 +1052,8 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
|
|
|
89be67 |
}
|
|
|
89be67 |
|
|
|
89be67 |
for ( ; num; num--) {
|
|
|
89be67 |
- if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
|
|
|
89be67 |
- file_badseek(ms);
|
|
|
89be67 |
- return -1;
|
|
|
89be67 |
- }
|
|
|
89be67 |
-
|
|
|
89be67 |
- if (read(fd, xph_addr, xph_sizeof) == -1) {
|
|
|
89be67 |
- file_badread(ms);
|
|
|
89be67 |
+ if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
|
|
|
89be67 |
+ file_badread(ms);
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
}
|
|
|
89be67 |
|
|
|
89be67 |
@@ -1096,12 +1091,9 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
|
|
|
89be67 |
* This is a PT_NOTE section; loop through all the notes
|
|
|
89be67 |
* in the section.
|
|
|
89be67 |
*/
|
|
|
89be67 |
- if (lseek(fd, xph_offset, SEEK_SET) == (off_t)-1) {
|
|
|
89be67 |
- file_badseek(ms);
|
|
|
89be67 |
- return -1;
|
|
|
89be67 |
- }
|
|
|
89be67 |
- bufsize = read(fd, nbuf, ((xph_filesz < sizeof(nbuf)) ?
|
|
|
89be67 |
- xph_filesz : sizeof(nbuf)));
|
|
|
89be67 |
+ len = xph_filesz < sizeof(nbuf) ? xph_filesz
|
|
|
89be67 |
+ : sizeof(nbuf);
|
|
|
89be67 |
+ bufsize = pread(fd, nbuf, len, xph_offset);
|
|
|
89be67 |
if (bufsize == -1) {
|
|
|
89be67 |
file_badread(ms);
|
|
|
89be67 |
return -1;
|