summaryrefslogtreecommitdiff
path: root/src/readelf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/readelf.c')
-rw-r--r--src/readelf.c305
1 files changed, 194 insertions, 111 deletions
diff --git a/src/readelf.c b/src/readelf.c
index 3df0836d7029e..db0b35a506a71 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.141 2018/04/12 16:50:52 christos Exp $")
+FILE_RCSID("@(#)$File: readelf.c,v 1.144 2018/07/08 23:37:33 christos Exp $")
#endif
#ifdef BUILTIN_ELF
@@ -62,13 +62,12 @@ private uint64_t getu64(int, uint64_t);
#define MAX_PHNUM 128
#define MAX_SHNUM 32768
-#define SIZE_UNKNOWN ((off_t)-1)
+#define SIZE_UNKNOWN CAST(off_t, -1)
private int
toomany(struct magic_set *ms, const char *name, uint16_t num)
{
- if (file_printf(ms, ", too many %s (%u)", name, num
- ) == -1)
+ if (file_printf(ms, ", too many %s (%u)", name, num) == -1)
return -1;
return 0;
}
@@ -143,54 +142,55 @@ getu64(int swap, uint64_t value)
#define elf_getu64(swap, value) getu64(swap, value)
#define xsh_addr (clazz == ELFCLASS32 \
- ? (void *)&sh32 \
- : (void *)&sh64)
+ ? CAST(void *, &sh32) \
+ : CAST(void *, &sh64))
#define xsh_sizeof (clazz == ELFCLASS32 \
? sizeof(sh32) \
: sizeof(sh64))
-#define xsh_size (size_t)(clazz == ELFCLASS32 \
+#define xsh_size CAST(size_t, (clazz == ELFCLASS32 \
? elf_getu32(swap, sh32.sh_size) \
- : elf_getu64(swap, sh64.sh_size))
-#define xsh_offset (off_t)(clazz == ELFCLASS32 \
+ : elf_getu64(swap, sh64.sh_size)))
+#define xsh_offset CAST(off_t, (clazz == ELFCLASS32 \
? elf_getu32(swap, sh32.sh_offset) \
- : elf_getu64(swap, sh64.sh_offset))
+ : elf_getu64(swap, sh64.sh_offset)))
#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)
+ ? CAST(void *, &ph32) \
+ : CAST(void *, &ph64))
#define xph_sizeof (clazz == ELFCLASS32 \
? sizeof(ph32) \
: sizeof(ph64))
#define xph_type (clazz == ELFCLASS32 \
? elf_getu32(swap, ph32.p_type) \
: elf_getu32(swap, ph64.p_type))
-#define xph_offset (off_t)(clazz == ELFCLASS32 \
+#define xph_offset CAST(off_t, (clazz == ELFCLASS32 \
? elf_getu32(swap, ph32.p_offset) \
- : elf_getu64(swap, ph64.p_offset))
-#define xph_align (size_t)((clazz == ELFCLASS32 \
- ? (off_t) (ph32.p_align ? \
- elf_getu32(swap, ph32.p_align) : 4) \
- : (off_t) (ph64.p_align ? \
- elf_getu64(swap, ph64.p_align) : 4)))
-#define xph_vaddr (size_t)((clazz == ELFCLASS32 \
- ? (off_t) (ph32.p_vaddr ? \
- elf_getu32(swap, ph32.p_vaddr) : 4) \
- : (off_t) (ph64.p_vaddr ? \
- elf_getu64(swap, ph64.p_vaddr) : 4)))
-#define xph_filesz (size_t)((clazz == ELFCLASS32 \
+ : elf_getu64(swap, ph64.p_offset)))
+#define xph_align CAST(size_t, (clazz == ELFCLASS32 \
+ ? CAST(off_t, (ph32.p_align ? \
+ elf_getu32(swap, ph32.p_align) : 4))\
+ : CAST(off_t, (ph64.p_align ? \
+ elf_getu64(swap, ph64.p_align) : 4))))
+#define xph_vaddr CAST(size_t, (clazz == ELFCLASS32 \
+ ? CAST(off_t, (ph32.p_vaddr ? \
+ elf_getu32(swap, ph32.p_vaddr) : 4))\
+ : CAST(off_t, (ph64.p_vaddr ? \
+ elf_getu64(swap, ph64.p_vaddr) : 4))))
+#define xph_filesz CAST(size_t, (clazz == ELFCLASS32 \
? elf_getu32(swap, ph32.p_filesz) \
: elf_getu64(swap, ph64.p_filesz)))
-#define xnh_addr (clazz == ELFCLASS32 \
- ? (void *)&nh32 \
- : (void *)&nh64)
-#define xph_memsz (size_t)((clazz == ELFCLASS32 \
+#define xph_memsz CAST(size_t, ((clazz == ELFCLASS32 \
? elf_getu32(swap, ph32.p_memsz) \
- : elf_getu64(swap, ph64.p_memsz)))
+ : elf_getu64(swap, ph64.p_memsz))))
+#define xnh_addr (clazz == ELFCLASS32 \
+ ? CAST(void *, &nh32) \
+ : CAST(void *, &nh64))
#define xnh_sizeof (clazz == ELFCLASS32 \
? sizeof(nh32) \
: sizeof(nh64))
@@ -203,24 +203,36 @@ getu64(int swap, uint64_t value)
#define xnh_descsz (clazz == ELFCLASS32 \
? elf_getu32(swap, nh32.n_descsz) \
: elf_getu32(swap, nh64.n_descsz))
-#define prpsoffsets(i) (clazz == ELFCLASS32 \
- ? prpsoffsets32[i] \
- : prpsoffsets64[i])
+
+#define xdh_addr (clazz == ELFCLASS32 \
+ ? CAST(void *, &dh32) \
+ : CAST(void *, &dh64))
+#define xdh_sizeof (clazz == ELFCLASS32 \
+ ? sizeof(dh32) \
+ : sizeof(dh64))
+#define xdh_tag (clazz == ELFCLASS32 \
+ ? elf_getu32(swap, dh32.d_tag) \
+ : elf_getu64(swap, dh64.d_tag))
+#define xdh_val (clazz == ELFCLASS32 \
+ ? elf_getu32(swap, dh32.d_un.d_val) \
+ : elf_getu64(swap, dh64.d_un.d_val))
+
#define xcap_addr (clazz == ELFCLASS32 \
- ? (void *)&cap32 \
- : (void *)&cap64)
+ ? CAST(void *, &cap32) \
+ : CAST(void *, &cap64))
#define xcap_sizeof (clazz == ELFCLASS32 \
- ? sizeof cap32 \
- : sizeof cap64)
+ ? sizeof(cap32) \
+ : sizeof(cap64))
#define xcap_tag (clazz == ELFCLASS32 \
? elf_getu32(swap, cap32.c_tag) \
: elf_getu64(swap, cap64.c_tag))
#define xcap_val (clazz == ELFCLASS32 \
? elf_getu32(swap, cap32.c_un.c_val) \
: elf_getu64(swap, cap64.c_un.c_val))
+
#define xauxv_addr (clazz == ELFCLASS32 \
- ? (void *)&auxv32 \
- : (void *)&auxv64)
+ ? CAST(void *, &auxv32) \
+ : CAST(void *, &auxv64))
#define xauxv_sizeof (clazz == ELFCLASS32 \
? sizeof(auxv32) \
: sizeof(auxv64))
@@ -231,6 +243,10 @@ getu64(int swap, uint64_t value)
? elf_getu32(swap, auxv32.a_v) \
: elf_getu64(swap, auxv64.a_v))
+#define prpsoffsets(i) (clazz == ELFCLASS32 \
+ ? prpsoffsets32[i] \
+ : prpsoffsets64[i])
+
#ifdef ELFCORE
/*
* Try larger offsets first to avoid false matches
@@ -266,8 +282,8 @@ static const size_t prpsoffsets64[] = {
16, /* FreeBSD, 64-bit */
};
-#define NOFFSETS32 (sizeof prpsoffsets32 / sizeof prpsoffsets32[0])
-#define NOFFSETS64 (sizeof prpsoffsets64 / sizeof prpsoffsets64[0])
+#define NOFFSETS32 (sizeof(prpsoffsets32) / sizeof(prpsoffsets32[0]))
+#define NOFFSETS64 (sizeof(prpsoffsets64) / sizeof(prpsoffsets64[0]))
#define NOFFSETS (clazz == ELFCLASS32 ? NOFFSETS32 : NOFFSETS64)
@@ -346,7 +362,8 @@ 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 (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) {
+ if (pread(fd, xph_addr, xph_sizeof, off) <
+ CAST(ssize_t, xph_sizeof)) {
file_badread(ms);
return -1;
}
@@ -389,7 +406,7 @@ static void
do_note_netbsd_version(struct magic_set *ms, int swap, void *v)
{
uint32_t desc;
- (void)memcpy(&desc, v, sizeof(desc));
+ memcpy(&desc, v, sizeof(desc));
desc = elf_getu32(swap, desc);
if (file_printf(ms, ", for NetBSD") == -1)
@@ -435,7 +452,7 @@ do_note_freebsd_version(struct magic_set *ms, int swap, void *v)
{
uint32_t desc;
- (void)memcpy(&desc, v, sizeof(desc));
+ memcpy(&desc, v, sizeof(desc));
desc = elf_getu32(swap, desc);
if (file_printf(ms, ", for FreeBSD") == -1)
return;
@@ -533,12 +550,19 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
}
if (file_printf(ms, ", BuildID[%s]=", btype) == -1)
return 1;
- (void)memcpy(desc, &nbuf[doff], descsz);
+ memcpy(desc, &nbuf[doff], descsz);
for (i = 0; i < descsz; i++)
if (file_printf(ms, "%02x", desc[i]) == -1)
return 1;
return 1;
}
+ if (namesz == 4 && strcmp((char *)&nbuf[noff], "Go") == 0 &&
+ type == NT_GO_BUILD_ID && descsz < 128) {
+ if (file_printf(ms, ", Go BuildID=%s",
+ (char *)&nbuf[doff]) == -1)
+ return 1;
+ return 1;
+ }
return 0;
}
@@ -557,7 +581,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
type == NT_GNU_VERSION && descsz == 16) {
uint32_t desc[4];
- (void)memcpy(desc, &nbuf[doff], sizeof(desc));
+ memcpy(desc, &nbuf[doff], sizeof(desc));
*flags |= FLAGS_DID_OS_NOTE;
if (file_printf(ms, ", for GNU/") == -1)
@@ -624,7 +648,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
*flags |= FLAGS_DID_OS_NOTE;
if (file_printf(ms, ", for DragonFly") == -1)
return 1;
- (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
+ memcpy(&desc, &nbuf[doff], sizeof(desc));
desc = elf_getu32(swap, desc);
if (file_printf(ms, " %d.%d.%d", desc / 100000,
desc / 10000 % 10, desc % 10000) == -1)
@@ -654,7 +678,7 @@ do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
int did = 0;
*flags |= FLAGS_DID_NETBSD_PAX;
- (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
+ memcpy(&desc, &nbuf[doff], sizeof(desc));
desc = elf_getu32(swap, desc);
if (desc && file_printf(ms, ", PaX: ") == -1)
@@ -825,7 +849,8 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
cname = (unsigned char *)
&nbuf[doff + prpsoffsets(i)];
- for (cp = cname; *cp && isprint(*cp); cp++)
+ for (cp = cname; cp < nbuf + size && *cp
+ && isprint(*cp); cp++)
continue;
/*
* Linux apparently appends a space at the end
@@ -953,7 +978,7 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
nval = 0;
for (size_t off = 0; off + elsize <= descsz; off += elsize) {
- (void)memcpy(xauxv_addr, &nbuf[doff + off], xauxv_sizeof);
+ memcpy(xauxv_addr, &nbuf[doff + off], xauxv_sizeof);
/* Limit processing to 50 vector entries to prevent DoS */
if (nval++ >= 50) {
file_error(ms, 0, "Too many ELF Auxv elements");
@@ -1018,6 +1043,38 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
}
private size_t
+dodynamic(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
+ int clazz, int swap)
+{
+ Elf32_Dyn dh32;
+ Elf64_Dyn dh64;
+ unsigned char *dbuf = CAST(unsigned char *, vbuf);
+
+ if (xdh_sizeof + offset > size) {
+ /*
+ * We're out of note headers.
+ */
+ return xdh_sizeof + offset;
+ }
+
+ memcpy(xdh_addr, &dbuf[offset], xdh_sizeof);
+ offset += xdh_sizeof;
+
+ switch (xdh_tag) {
+ case DT_FLAGS_1:
+ if (xdh_val == DF_1_PIE)
+ ms->mode |= 0111;
+ else
+ ms->mode &= ~0111;
+ break;
+ default:
+ break;
+ }
+ return offset;
+}
+
+
+private size_t
donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
int clazz, int swap, size_t align, int *flags, uint16_t *notecount,
int fd, off_t ph_off, int ph_num, off_t fsize)
@@ -1039,7 +1096,7 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
return xnh_sizeof + offset;
}
- (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
+ memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
offset += xnh_sizeof;
namesz = xnh_namesz;
@@ -1053,14 +1110,14 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
}
if (namesz & 0x80000000) {
- (void)file_printf(ms, ", bad note name size %#lx",
- (unsigned long)namesz);
+ file_printf(ms, ", bad note name size %#lx",
+ CAST(unsigned long, namesz));
return 0;
}
if (descsz & 0x80000000) {
- (void)file_printf(ms, ", bad note description size %#lx",
- (unsigned long)descsz);
+ file_printf(ms, ", bad note description size %#lx",
+ CAST(unsigned long, descsz));
return 0;
}
@@ -1114,35 +1171,25 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
return offset;
}
- if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
+ if (namesz == 7 && strcmp(CAST(char *, &nbuf[noff]), "NetBSD") == 0) {
+ int descw, flag;
+ const char *str, *tag;
if (descsz > 100)
descsz = 100;
switch (xnh_type) {
case NT_NETBSD_VERSION:
return offset;
case NT_NETBSD_MARCH:
- if (*flags & FLAGS_DID_NETBSD_MARCH)
- return offset;
- *flags |= FLAGS_DID_NETBSD_MARCH;
- if (file_printf(ms, ", compiled for: %.*s",
- (int)descsz, (const char *)&nbuf[doff]) == -1)
- return offset;
+ flag = FLAGS_DID_NETBSD_MARCH;
+ tag = "compiled for";
break;
case NT_NETBSD_CMODEL:
- if (*flags & FLAGS_DID_NETBSD_CMODEL)
- return offset;
- *flags |= FLAGS_DID_NETBSD_CMODEL;
- if (file_printf(ms, ", compiler model: %.*s",
- (int)descsz, (const char *)&nbuf[doff]) == -1)
- return offset;
+ flag = FLAGS_DID_NETBSD_CMODEL;
+ tag = "compiler model";
break;
case NT_NETBSD_EMULATION:
- if (*flags & FLAGS_DID_NETBSD_EMULATION)
- return offset;
- *flags |= FLAGS_DID_NETBSD_EMULATION;
- if (file_printf(ms, ", emulation: %.*s",
- (int)descsz, (const char *)&nbuf[doff]) == -1)
- return offset;
+ flag = FLAGS_DID_NETBSD_EMULATION;
+ tag = "emulation:";
break;
default:
if (*flags & FLAGS_DID_NETBSD_UNKNOWN)
@@ -1150,8 +1197,15 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
*flags |= FLAGS_DID_NETBSD_UNKNOWN;
if (file_printf(ms, ", note=%u", xnh_type) == -1)
return offset;
- break;
+ return offset;
}
+
+ if (*flags & flag)
+ return offset;
+ str = CAST(const char *, &nbuf[doff]);
+ descw = CAST(int, descsz);
+ *flags |= flag;
+ file_printf(ms, ", %s: %.*s", tag, descw, str);
return offset;
}
@@ -1232,7 +1286,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
/* Read offset of name section to be able to read section names later */
if (pread(fd, xsh_addr, xsh_sizeof, CAST(off_t, (off + size * strtab)))
- < (ssize_t)xsh_sizeof) {
+ < CAST(ssize_t, xsh_sizeof)) {
if (file_printf(ms, ", missing section headers") == -1)
return -1;
return 0;
@@ -1241,7 +1295,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
for ( ; num; num--) {
/* Read the name of this section. */
- if ((namesize = pread(fd, name, sizeof(name) - 1, name_off + xsh_name)) == -1) {
+ if ((namesize = pread(fd, name, sizeof(name) - 1,
+ name_off + xsh_name)) == -1) {
file_badread(ms);
return -1;
}
@@ -1251,7 +1306,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
stripped = 0;
}
- if (pread(fd, xsh_addr, xsh_sizeof, off) < (ssize_t)xsh_sizeof) {
+ if (pread(fd, xsh_addr, xsh_sizeof, off) <
+ CAST(ssize_t, xsh_sizeof)) {
file_badread(ms);
return -1;
}
@@ -1277,14 +1333,15 @@ 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 ((uintmax_t)(xsh_size + xsh_offset) >
- (uintmax_t)fsize) {
+ if (CAST(uintmax_t, (xsh_size + xsh_offset)) >
+ CAST(uintmax_t, fsize)) {
if (file_printf(ms,
", note offset/size %#" INTMAX_T_FORMAT
"x+%#" INTMAX_T_FORMAT "x exceeds"
" file size %#" INTMAX_T_FORMAT "x",
- (uintmax_t)xsh_offset, (uintmax_t)xsh_size,
- (uintmax_t)fsize) == -1)
+ CAST(uintmax_t, xsh_offset),
+ CAST(uintmax_t, xsh_size),
+ CAST(uintmax_t, fsize)) == -1)
return -1;
return 0;
}
@@ -1294,7 +1351,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
return -1;
}
if (pread(fd, nbuf, xsh_size, xsh_offset) <
- (ssize_t)xsh_size) {
+ CAST(ssize_t, xsh_size)) {
file_badread(ms);
free(nbuf);
return -1;
@@ -1302,9 +1359,9 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
noff = 0;
for (;;) {
- if (noff >= (off_t)xsh_size)
+ if (noff >= CAST(off_t, xsh_size))
break;
- noff = donote(ms, nbuf, (size_t)noff,
+ noff = donote(ms, nbuf, CAST(size_t, noff),
xsh_size, clazz, swap, 4, flags, notecount,
fd, 0, 0, 0);
if (noff == 0)
@@ -1326,7 +1383,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
if (nbadcap > 5)
break;
- if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) {
+ if (lseek(fd, xsh_offset, SEEK_SET)
+ == CAST(off_t, -1)) {
file_badseek(ms);
return -1;
}
@@ -1335,11 +1393,12 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
Elf32_Cap cap32;
Elf64_Cap cap64;
char cbuf[/*CONSTCOND*/
- MAX(sizeof cap32, sizeof cap64)];
- if ((coff += xcap_sizeof) > (off_t)xsh_size)
+ MAX(sizeof(cap32), sizeof(cap64))];
+ if ((coff += xcap_sizeof) >
+ CAST(off_t, xsh_size))
break;
- if (read(fd, cbuf, (size_t)xcap_sizeof) !=
- (ssize_t)xcap_sizeof) {
+ if (read(fd, cbuf, CAST(size_t, xcap_sizeof)) !=
+ CAST(ssize_t, xcap_sizeof)) {
file_badread(ms);
return -1;
}
@@ -1373,7 +1432,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
#endif
break;
}
- (void)memcpy(xcap_addr, cbuf, xcap_sizeof);
+ memcpy(xcap_addr, cbuf, xcap_sizeof);
switch (xcap_tag) {
case CA_SUNW_NULL:
break;
@@ -1388,8 +1447,9 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
", with unknown capability "
"%#" INT64_T_FORMAT "x = %#"
INT64_T_FORMAT "x",
- (unsigned long long)xcap_tag,
- (unsigned long long)xcap_val) == -1)
+ CAST(unsigned long long, xcap_tag),
+ CAST(unsigned long long, xcap_val))
+ == -1)
return -1;
if (nbadcap++ > 2)
coff = xsh_size;
@@ -1442,12 +1502,12 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
if (file_printf(ms,
" unknown hardware capability %#"
INT64_T_FORMAT "x",
- (unsigned long long)cap_hw1) == -1)
+ CAST(unsigned long long, cap_hw1)) == -1)
return -1;
} else {
if (file_printf(ms,
" hardware capability %#" INT64_T_FORMAT "x",
- (unsigned long long)cap_hw1) == -1)
+ CAST(unsigned long long, cap_hw1)) == -1)
return -1;
}
}
@@ -1464,7 +1524,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
if (file_printf(ms,
", with unknown software capability %#"
INT64_T_FORMAT "x",
- (unsigned long long)cap_sf1) == -1)
+ CAST(unsigned long long, cap_sf1)) == -1)
return -1;
}
return 0;
@@ -1483,9 +1543,9 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
Elf32_Phdr ph32;
Elf64_Phdr ph64;
const char *linking_style = "statically";
- const char *interp = "";
unsigned char nbuf[BUFSIZ];
char ibuf[BUFSIZ];
+ char interp[BUFSIZ];
ssize_t bufsize;
size_t offset, align, len;
@@ -1495,8 +1555,11 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
return 0;
}
+ interp[0] = '\0';
for ( ; num; num--) {
- if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) {
+ int doread;
+ if (pread(fd, xph_addr, xph_sizeof, off) <
+ CAST(ssize_t, xph_sizeof)) {
file_badread(ms);
return -1;
}
@@ -1509,6 +1572,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
switch (xph_type) {
case PT_DYNAMIC:
linking_style = "dynamically";
+ doread = 1;
break;
case PT_NOTE:
if (sh_num) /* Did this through section headers */
@@ -1517,21 +1581,16 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
align < 4) {
if (file_printf(ms,
", invalid note alignment %#lx",
- (unsigned long)align) == -1)
+ CAST(unsigned long, align)) == -1)
return -1;
align = 4;
}
/*FALLTHROUGH*/
case PT_INTERP:
- len = xph_filesz < sizeof(nbuf) ? xph_filesz
- : sizeof(nbuf);
- bufsize = pread(fd, nbuf, len, xph_offset);
- if (bufsize == -1) {
- file_badread(ms);
- return -1;
- }
+ doread = 1;
break;
default:
+ doread = 0;
if (fsize != SIZE_UNKNOWN && xph_offset > fsize) {
/* Maybe warn here? */
continue;
@@ -1539,14 +1598,37 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
break;
}
+ if (doread) {
+ len = xph_filesz < sizeof(nbuf) ? xph_filesz
+ : sizeof(nbuf);
+ bufsize = pread(fd, nbuf, len, xph_offset);
+ if (bufsize == -1) {
+ file_badread(ms);
+ return -1;
+ }
+ } else
+ len = 0;
+
/* Things we can determine when we seek */
switch (xph_type) {
+ case PT_DYNAMIC:
+ offset = 0;
+ for (;;) {
+ if (offset >= (size_t)bufsize)
+ break;
+ offset = dodynamic(ms, nbuf, offset,
+ CAST(size_t, bufsize), clazz, swap);
+ if (offset == 0)
+ break;
+ }
+ break;
+
case PT_INTERP:
if (bufsize && nbuf[0]) {
nbuf[bufsize - 1] = '\0';
- interp = (const char *)nbuf;
+ memcpy(interp, nbuf, bufsize);
} else
- interp = "*empty*";
+ strlcpy(interp, "*empty*", sizeof(interp));
break;
case PT_NOTE:
/*
@@ -1558,7 +1640,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
if (offset >= (size_t)bufsize)
break;
offset = donote(ms, nbuf, offset,
- (size_t)bufsize, clazz, swap, align,
+ CAST(size_t, bufsize), clazz, swap, align,
flags, notecount, fd, 0, 0, 0);
if (offset == 0)
break;
@@ -1587,7 +1669,7 @@ file_tryelf(struct magic_set *ms, const struct buffer *b)
size_t nbytes = b->flen;
union {
int32_t l;
- char c[sizeof (int32_t)];
+ char c[sizeof(int32_t)];
} u;
int clazz;
int swap;
@@ -1615,7 +1697,8 @@ file_tryelf(struct magic_set *ms, const struct buffer *b)
/*
* If we cannot seek, it must be a pipe, socket or fifo.
*/
- if((lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
+ if((lseek(fd, CAST(off_t, 0), SEEK_SET) == CAST(off_t, -1))
+ && (errno == ESPIPE))
fd = file_pipe2file(ms, fd, buf, nbytes);
if (fstat(fd, &st) == -1) {