diff --git a/SOURCES/file-5.33-floating-point-exception.patch b/SOURCES/file-5.33-floating-point-exception.patch new file mode 100644 index 0000000..32415b4 --- /dev/null +++ b/SOURCES/file-5.33-floating-point-exception.patch @@ -0,0 +1,77 @@ +diff --git a/src/Makefile.am b/src/Makefile.am +index a9b245d..c7f184d 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -17,10 +17,10 @@ MINGWLIBS = -lgnurx -lshlwapi + else + MINGWLIBS = + endif +-libmagic_la_LIBADD = $(LTLIBOBJS) $(MINGWLIBS) ++libmagic_la_LIBADD = -lm $(LTLIBOBJS) $(MINGWLIBS) + + file_SOURCES = file.c seccomp.c +-file_LDADD = libmagic.la ++file_LDADD = libmagic.la -lm + CLEANFILES = magic.h + EXTRA_DIST = magic.h.in + HDR= $(top_srcdir)/src/magic.h.in +diff --git a/src/softmagic.c b/src/softmagic.c +index 3e76517..57b4677 100644 +--- a/src/softmagic.c ++++ b/src/softmagic.c +@@ -37,6 +37,7 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.259 2018/03/11 01:23:52 christos Exp $") + + #include "magic.h" + #include ++#include + #include + #include + #include +@@ -1893,19 +1894,19 @@ magiccheck(struct magic_set *ms, struct magic *m) + break; + + case '!': +- matched = fv != fl; ++ matched = isunordered(fl, fv) ? 1 : fv != fl; + break; + + case '=': +- matched = fv == fl; ++ matched = isunordered(fl, fv) ? 0 : fv == fl; + break; + + case '>': +- matched = fv > fl; ++ matched = isgreater(fv, fl); + break; + + case '<': +- matched = fv < fl; ++ matched = isless(fv, fl); + break; + + default: +@@ -1926,19 +1927,19 @@ magiccheck(struct magic_set *ms, struct magic *m) + break; + + case '!': +- matched = dv != dl; ++ matched = isunordered(dv, dl) ? 1 : dv != dl; + break; + + case '=': +- matched = dv == dl; ++ matched = isunordered(dv, dl) ? 0 : dv == dl; + break; + + case '>': +- matched = dv > dl; ++ matched = isgreater(dv, dl); + break; + + case '<': +- matched = dv < dl; ++ matched = isless(dv, dl); + break; + + default: diff --git a/SOURCES/file-5.33-static-PIE-binaries-0.patch b/SOURCES/file-5.33-static-PIE-binaries-0.patch new file mode 100644 index 0000000..1031626 --- /dev/null +++ b/SOURCES/file-5.33-static-PIE-binaries-0.patch @@ -0,0 +1,236 @@ +From 3951ed6ab1ba4b7d6d4d2dd5700858c470627c46 Mon Sep 17 00:00:00 2001 +From: Vincent Mihalkovic +Date: Thu, 9 Feb 2023 16:46:43 +0100 +Subject: [PATCH] store copy of the mode info in the magic_set + +--- + src/file.h | 1 + + src/funcs.c | 53 +++++++++++++++++++++++++++++++------------------ + src/softmagic.c | 27 +++++++++++-------------- + 3 files changed, 47 insertions(+), 34 deletions(-) + +diff --git a/src/file.h b/src/file.h +index 66598bc..b3d015d 100644 +--- a/src/file.h ++++ b/src/file.h +@@ -413,6 +413,7 @@ struct magic_set { + #define EVENT_HAD_ERR 0x01 + const char *file; + size_t line; /* current magic line number */ ++ mode_t mode; /* copy of current stat mode */ + + /* data for searches */ + struct { +diff --git a/src/funcs.c b/src/funcs.c +index f59f4a1..0bf92fe 100644 +--- a/src/funcs.c ++++ b/src/funcs.c +@@ -27,7 +27,7 @@ + #include "file.h" + + #ifndef lint +-FILE_RCSID("@(#)$File: funcs.c,v 1.94 2017/11/02 20:25:39 christos Exp $") ++FILE_RCSID("@(#)$File: funcs.c,v 1.95 2018/05/24 18:09:17 christos Exp $") + #endif /* lint */ + + #include "magic.h" +@@ -183,9 +183,11 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u + const char *type = "application/octet-stream"; + const char *def = "data"; + const char *ftype = NULL; ++ char *rbuf = NULL; + struct buffer b; + + buffer_init(&b, fd, buf, nb); ++ ms->mode = b.st.st_mode; + + if (nb == 0) { + def = "empty"; +@@ -248,31 +250,43 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u + goto done; + } + } ++#ifdef BUILTIN_ELF ++ if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && nb > 5 && fd != -1) { ++ file_pushbuf_t *pb; ++ /* ++ * We matched something in the file, so this ++ * *might* be an ELF file, and the file is at ++ * least 5 bytes long, so if it's an ELF file ++ * it has at least one byte past the ELF magic ++ * number - try extracting information from the ++ * ELF headers that cannot easily be extracted ++ * with rules in the magic file. We we don't ++ * print the information yet. ++ */ ++ if ((pb = file_push_buffer(ms)) == NULL) ++ return -1; ++ ++ rv = file_tryelf(ms, &b); ++ rbuf = file_pop_buffer(ms, pb); ++ if (rv != 1) { ++ free(rbuf); ++ rbuf = NULL; ++ } ++ if ((ms->flags & MAGIC_DEBUG) != 0) ++ (void)fprintf(stderr, "[try elf %d]\n", m); ++ } ++#endif + + /* try soft magic tests */ + if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0) { + m = file_softmagic(ms, &b, NULL, NULL, BINTEST, looks_text); + if ((ms->flags & MAGIC_DEBUG) != 0) + (void)fprintf(stderr, "[try softmagic %d]\n", m); ++ if (m == 1 && rbuf) { ++ if (file_printf(ms, "%s", rbuf) == -1) ++ goto done; ++ } + if (m) { +-#ifdef BUILTIN_ELF +- if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && m == 1 && +- nb > 5 && fd != -1) { +- /* +- * We matched something in the file, so this +- * *might* be an ELF file, and the file is at +- * least 5 bytes long, so if it's an ELF file +- * it has at least one byte past the ELF magic +- * number - try extracting information from the +- * ELF headers that cannot easily * be +- * extracted with rules in the magic file. +- */ +- m = file_tryelf(ms, &b); +- if ((ms->flags & MAGIC_DEBUG) != 0) +- (void)fprintf(stderr, "[try elf %d]\n", +- m); +- } +-#endif + if (checkdone(ms, &rv)) + goto done; + } +@@ -318,6 +332,7 @@ simple: + #if HAVE_FORK + done_encoding: + #endif ++ free(rbuf); + buffer_fini(&b); + if (rv) + return rv; +diff --git a/src/softmagic.c b/src/softmagic.c +index 57b4677..0197ec4 100644 +--- a/src/softmagic.c ++++ b/src/softmagic.c +@@ -54,8 +54,7 @@ private int mget(struct magic_set *, struct magic *, const struct buffer *, + private int msetoffset(struct magic_set *, struct magic *, struct buffer *, + const struct buffer *, size_t, unsigned int); + private int magiccheck(struct magic_set *, struct magic *); +-private int32_t mprint(struct magic_set *, struct magic *, +- const struct buffer *); ++private int32_t mprint(struct magic_set *, struct magic *); + private int moffset(struct magic_set *, struct magic *, const struct buffer *, + int32_t *); + private void mdebug(uint32_t, const char *, size_t); +@@ -63,8 +62,7 @@ private int mcopy(struct magic_set *, union VALUETYPE *, int, int, + const unsigned char *, uint32_t, size_t, struct magic *); + private int mconvert(struct magic_set *, struct magic *, int); + private int print_sep(struct magic_set *, int); +-private int handle_annotation(struct magic_set *, struct magic *, +- const struct buffer *, int); ++private int handle_annotation(struct magic_set *, struct magic *, int); + private int cvt_8(union VALUETYPE *, const struct magic *); + private int cvt_16(union VALUETYPE *, const struct magic *); + private int cvt_32(union VALUETYPE *, const struct magic *); +@@ -241,7 +239,7 @@ flush: + goto flush; + } + +- if ((e = handle_annotation(ms, m, b, firstline)) != 0) { ++ if ((e = handle_annotation(ms, m, firstline)) != 0) { + *need_separator = 1; + *printed_something = 1; + *returnval = 1; +@@ -259,7 +257,7 @@ flush: + return -1; + } + +- if (print && mprint(ms, m, b) == -1) ++ if (print && mprint(ms, m) == -1) + return -1; + + switch (moffset(ms, m, &bb, &ms->c.li[cont_level].off)) { +@@ -340,7 +338,7 @@ flush: + } else + ms->c.li[cont_level].got_match = 1; + +- if ((e = handle_annotation(ms, m, b, firstline)) ++ if ((e = handle_annotation(ms, m, firstline)) + != 0) { + *need_separator = 1; + *printed_something = 1; +@@ -374,7 +372,7 @@ flush: + return -1; + *need_separator = 0; + } +- if (print && mprint(ms, m, b) == -1) ++ if (print && mprint(ms, m) == -1) + return -1; + + switch (moffset(ms, m, &bb, +@@ -454,7 +452,7 @@ strndup(const char *str, size_t n) + #endif /* HAVE_STRNDUP */ + + static int +-varexpand(char *buf, size_t len, const struct buffer *b, const char *str) ++varexpand(struct magic_set *ms, char *buf, size_t len, const char *str) + { + const char *ptr, *sptr, *e, *t, *ee, *et; + size_t l; +@@ -479,7 +477,7 @@ varexpand(char *buf, size_t len, const struct buffer *b, const char *str) + return -1; + switch (*ptr) { + case 'x': +- if (b->st.st_mode & 0111) { ++ if (ms->mode & 0111) { + ptr = t; + l = et - t; + } else { +@@ -509,7 +507,7 @@ varexpand(char *buf, size_t len, const struct buffer *b, const char *str) + + + private int32_t +-mprint(struct magic_set *ms, struct magic *m, const struct buffer *b) ++mprint(struct magic_set *ms, struct magic *m) + { + uint64_t v; + float vf; +@@ -519,7 +517,7 @@ mprint(struct magic_set *ms, struct magic *m, const struct buffer *b) + const char *desc; + union VALUETYPE *p = &ms->ms_value; + +- if (varexpand(ebuf, sizeof(ebuf), b, m->desc) == -1) ++ if (varexpand(ms, ebuf, sizeof(ebuf), m->desc) == -1) + desc = m->desc; + else + desc = ebuf; +@@ -2166,8 +2164,7 @@ magiccheck(struct magic_set *ms, struct magic *m) + } + + private int +-handle_annotation(struct magic_set *ms, struct magic *m, const struct buffer *b, +- int firstline) ++handle_annotation(struct magic_set *ms, struct magic *m, int firstline) + { + if ((ms->flags & MAGIC_APPLE) && m->apple[0]) { + if (!firstline && file_printf(ms, "\n- ") == -1) +@@ -2188,7 +2185,7 @@ handle_annotation(struct magic_set *ms, struct magic *m, const struct buffer *b, + const char *p; + if (!firstline && file_printf(ms, "\n- ") == -1) + return -1; +- if (varexpand(buf, sizeof(buf), b, m->mimetype) == -1) ++ if (varexpand(ms, buf, sizeof(buf), m->mimetype) == -1) + p = m->mimetype; + else + p = buf; +-- +2.39.1 + diff --git a/SOURCES/file-5.33-static-PIE-binaries-1.patch b/SOURCES/file-5.33-static-PIE-binaries-1.patch new file mode 100644 index 0000000..35a6e97 --- /dev/null +++ b/SOURCES/file-5.33-static-PIE-binaries-1.patch @@ -0,0 +1,767 @@ +From 493e2676626b530a45fcc17040915f34fa0c5dd3 Mon Sep 17 00:00:00 2001 +From: Vincent Mihalkovic +Date: Mon, 6 Feb 2023 14:39:29 +0100 +Subject: [PATCH] add parsing for dynamic sections + +9109a696f3289ba00eaa222fd432755ec4287e28 +--- + src/readelf.c | 295 +++++++++++++++++++++++++++++++------------------- + src/readelf.h | 103 ++++++++++++++++++ + 2 files changed, 289 insertions(+), 109 deletions(-) + +diff --git a/src/readelf.c b/src/readelf.c +index c101483..cdc211f 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -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 +@@ -269,8 +285,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) + +@@ -349,7 +365,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; + } +@@ -392,7 +409,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) +@@ -438,7 +455,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; +@@ -536,7 +553,7 @@ 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; +@@ -560,7 +577,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) +@@ -627,7 +644,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) +@@ -657,7 +674,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) +@@ -957,7 +974,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"); +@@ -1021,6 +1038,38 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, + #endif + } + ++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, +@@ -1043,7 +1092,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; +@@ -1057,14 +1106,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; + } + +@@ -1118,35 +1167,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) +@@ -1154,8 +1193,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; + } + +@@ -1236,7 +1282,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; +@@ -1245,7 +1291,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; + } +@@ -1255,7 +1302,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; + } +@@ -1281,14 +1329,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; + } +@@ -1298,7 +1347,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; +@@ -1306,9 +1355,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) +@@ -1330,7 +1379,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; + } +@@ -1339,11 +1389,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; + } +@@ -1377,7 +1428,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; +@@ -1392,8 +1443,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; +@@ -1446,12 +1498,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; + } + } +@@ -1468,7 +1520,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; +@@ -1487,9 +1539,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; + +@@ -1499,8 +1551,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; + } +@@ -1513,6 +1568,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 */ +@@ -1521,21 +1577,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; +@@ -1543,14 +1594,39 @@ 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; ++ } ++ if (ms->flags & MAGIC_MIME) ++ continue; ++ 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: + /* +@@ -1562,7 +1638,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; +@@ -1591,7 +1667,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; +@@ -1619,7 +1695,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) { +diff --git a/src/readelf.h b/src/readelf.h +index ef880b9..f2f3dc3 100644 +--- a/src/readelf.h ++++ b/src/readelf.h +@@ -430,4 +430,107 @@ typedef struct { + #define AV_386_SSE4_1 0x00800000 + #define AV_386_SSE4_2 0x01000000 + ++/* ++ * Dynamic Section structure array ++ */ ++typedef struct { ++ Elf32_Word d_tag; /* entry tag value */ ++ union { ++ Elf32_Addr d_ptr; ++ Elf32_Word d_val; ++ } d_un; ++} Elf32_Dyn; ++ ++typedef struct { ++ Elf64_Xword d_tag; /* entry tag value */ ++ union { ++ Elf64_Addr d_ptr; ++ Elf64_Xword d_val; ++ } d_un; ++} Elf64_Dyn; ++ ++/* d_tag */ ++#define DT_NULL 0 /* Marks end of dynamic array */ ++#define DT_NEEDED 1 /* Name of needed library (DT_STRTAB offset) */ ++#define DT_PLTRELSZ 2 /* Size, in bytes, of relocations in PLT */ ++#define DT_PLTGOT 3 /* Address of PLT and/or GOT */ ++#define DT_HASH 4 /* Address of symbol hash table */ ++#define DT_STRTAB 5 /* Address of string table */ ++#define DT_SYMTAB 6 /* Address of symbol table */ ++#define DT_RELA 7 /* Address of Rela relocation table */ ++#define DT_RELASZ 8 /* Size, in bytes, of DT_RELA table */ ++#define DT_RELAENT 9 /* Size, in bytes, of one DT_RELA entry */ ++#define DT_STRSZ 10 /* Size, in bytes, of DT_STRTAB table */ ++#define DT_SYMENT 11 /* Size, in bytes, of one DT_SYMTAB entry */ ++#define DT_INIT 12 /* Address of initialization function */ ++#define DT_FINI 13 /* Address of termination function */ ++#define DT_SONAME 14 /* Shared object name (DT_STRTAB offset) */ ++#define DT_RPATH 15 /* Library search path (DT_STRTAB offset) */ ++#define DT_SYMBOLIC 16 /* Start symbol search within local object */ ++#define DT_REL 17 /* Address of Rel relocation table */ ++#define DT_RELSZ 18 /* Size, in bytes, of DT_REL table */ ++#define DT_RELENT 19 /* Size, in bytes, of one DT_REL entry */ ++#define DT_PLTREL 20 /* Type of PLT relocation entries */ ++#define DT_DEBUG 21 /* Used for debugging; unspecified */ ++#define DT_TEXTREL 22 /* Relocations might modify non-writable seg */ ++#define DT_JMPREL 23 /* Address of relocations associated with PLT */ ++#define DT_BIND_NOW 24 /* Process all relocations at load-time */ ++#define DT_INIT_ARRAY 25 /* Address of initialization function array */ ++#define DT_FINI_ARRAY 26 /* Size, in bytes, of DT_INIT_ARRAY array */ ++#define DT_INIT_ARRAYSZ 27 /* Address of termination function array */ ++#define DT_FINI_ARRAYSZ 28 /* Size, in bytes, of DT_FINI_ARRAY array*/ ++#define DT_RUNPATH 29 /* overrides DT_RPATH */ ++#define DT_FLAGS 30 /* Encodes ORIGIN, SYMBOLIC, TEXTREL, BIND_NOW, STATIC_TLS */ ++#define DT_ENCODING 31 /* ??? */ ++#define DT_PREINIT_ARRAY 32 /* Address of pre-init function array */ ++#define DT_PREINIT_ARRAYSZ 33 /* Size, in bytes, of DT_PREINIT_ARRAY array */ ++#define DT_NUM 34 ++ ++#define DT_LOOS 0x60000000 /* Operating system specific range */ ++#define DT_VERSYM 0x6ffffff0 /* Symbol versions */ ++#define DT_FLAGS_1 0x6ffffffb /* ELF dynamic flags */ ++#define DT_VERDEF 0x6ffffffc /* Versions defined by file */ ++#define DT_VERDEFNUM 0x6ffffffd /* Number of versions defined by file */ ++#define DT_VERNEED 0x6ffffffe /* Versions needed by file */ ++#define DT_VERNEEDNUM 0x6fffffff /* Number of versions needed by file */ ++#define DT_HIOS 0x6fffffff ++#define DT_LOPROC 0x70000000 /* Processor-specific range */ ++#define DT_HIPROC 0x7fffffff ++ ++/* Flag values for DT_FLAGS */ ++#define DF_ORIGIN 0x00000001 /* uses $ORIGIN */ ++#define DF_SYMBOLIC 0x00000002 /* */ ++#define DF_TEXTREL 0x00000004 /* */ ++#define DF_BIND_NOW 0x00000008 /* */ ++#define DF_STATIC_TLS 0x00000010 /* */ ++ ++/* Flag values for DT_FLAGS_1 */ ++#define DF_1_NOW 0x00000001 /* Same as DF_BIND_NOW */ ++#define DF_1_GLOBAL 0x00000002 /* Unused */ ++#define DF_1_GROUP 0x00000004 /* Is member of group */ ++#define DF_1_NODELETE 0x00000008 /* Cannot be deleted from process */ ++#define DF_1_LOADFLTR 0x00000010 /* Immediate loading of filters */ ++#define DF_1_INITFIRST 0x00000020 /* init/fini takes priority */ ++#define DF_1_NOOPEN 0x00000040 /* Do not allow loading on dlopen() */ ++#define DF_1_ORIGIN 0x00000080 /* Require $ORIGIN processing */ ++#define DF_1_DIRECT 0x00000100 /* Enable direct bindings */ ++#define DF_1_INTERPOSE 0x00000400 /* Is an interposer */ ++#define DF_1_NODEFLIB 0x00000800 /* Ignore default library search path */ ++#define DF_1_NODUMP 0x00001000 /* Cannot be dumped with dldump(3C) */ ++#define DF_1_CONFALT 0x00002000 /* Configuration alternative */ ++#define DF_1_ENDFILTEE 0x00004000 /* Filtee ends filter's search */ ++#define DF_1_DISPRELDNE 0x00008000 /* Did displacement relocation */ ++#define DF_1_DISPRELPND 0x00010000 /* Pending displacement relocation */ ++#define DF_1_NODIRECT 0x00020000 /* Has non-direct bindings */ ++#define DF_1_IGNMULDEF 0x00040000 /* Used internally */ ++#define DF_1_NOKSYMS 0x00080000 /* Used internally */ ++#define DF_1_NOHDR 0x00100000 /* Used internally */ ++#define DF_1_EDITED 0x00200000 /* Has been modified since build */ ++#define DF_1_NORELOC 0x00400000 /* Used internally */ ++#define DF_1_SYMINTPOSE 0x00800000 /* Has individual symbol interposers */ ++#define DF_1_GLOBAUDIT 0x01000000 /* Require global auditing */ ++#define DF_1_SINGLETON 0x02000000 /* Has singleton symbols */ ++#define DF_1_STUB 0x04000000 /* Stub */ ++#define DF_1_PIE 0x08000000 /* Position Independent Executable */ ++ + #endif +-- +2.39.1 + diff --git a/SOURCES/file-5.33-static-PIE-binaries-2.patch b/SOURCES/file-5.33-static-PIE-binaries-2.patch new file mode 100644 index 0000000..85446ae --- /dev/null +++ b/SOURCES/file-5.33-static-PIE-binaries-2.patch @@ -0,0 +1,68 @@ +From f8ba1437114e408de0f66efb272fdc1de986017a Mon Sep 17 00:00:00 2001 +From: Vincent Mihalkovic +Date: Mon, 6 Feb 2023 14:39:58 +0100 +Subject: [PATCH] We need to process the dynamic section so that we can set $x + for mime. + +9ffbd485ba4647827c4bdacf3a2de690f6765b0c +--- + src/readelf.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/src/readelf.c b/src/readelf.c +index cdc211f..94cdaca 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -1273,6 +1273,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, + uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilities */ + char name[50]; + ssize_t namesize; ++ if (ms->flags & MAGIC_MIME) ++ return 0; + + if (size != xsh_sizeof) { + if (file_printf(ms, ", corrupted section header size") == -1) +@@ -1622,6 +1624,8 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + break; + + case PT_INTERP: ++ if (ms->flags & MAGIC_MIME) ++ continue; + if (bufsize && nbuf[0]) { + nbuf[bufsize - 1] = '\0'; + memcpy(interp, nbuf, bufsize); +@@ -1629,6 +1633,8 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + strlcpy(interp, "*empty*", sizeof(interp)); + break; + case PT_NOTE: ++ if (ms->flags & MAGIC_MIME) ++ return 0; + /* + * This is a PT_NOTE section; loop through all the notes + * in the section. +@@ -1645,9 +1651,13 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + } + break; + default: ++ if (ms->flags & MAGIC_MIME) ++ continue; + break; + } + } ++ if (ms->flags & MAGIC_MIME) ++ return 0; + if (file_printf(ms, ", %s linked", linking_style) + == -1) + return -1; +@@ -1678,7 +1688,7 @@ file_tryelf(struct magic_set *ms, const struct buffer *b) + Elf64_Ehdr elf64hdr; + uint16_t type, phnum, shnum, notecount; + +- if (ms->flags & (MAGIC_MIME|MAGIC_APPLE|MAGIC_EXTENSION)) ++ if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) + return 0; + /* + * ELF executables have multiple section headers in arbitrary +-- +2.39.1 + diff --git a/SOURCES/file-5.33-static-PIE-binaries-3.patch b/SOURCES/file-5.33-static-PIE-binaries-3.patch new file mode 100644 index 0000000..13314a1 --- /dev/null +++ b/SOURCES/file-5.33-static-PIE-binaries-3.patch @@ -0,0 +1,36 @@ +From 27c951adbd5d7ebe95f08c18257ea031bdd59ee1 Mon Sep 17 00:00:00 2001 +From: Vincent Mihalkovic +Date: Mon, 6 Feb 2023 15:00:16 +0100 +Subject: [PATCH] For dynamic binaries let the df_1 pie flag determine if we + are pie or a shared object, and ignore the mode bits. + +upstream commit: 03084b161cf888b5286dbbcd964c31ccad4f64d9 +--- + src/readelf.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/readelf.c b/src/readelf.c +index 94cdaca..9c75c0a 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -1058,7 +1058,7 @@ dodynamic(struct magic_set *ms, void *vbuf, size_t offset, size_t size, + + switch (xdh_tag) { + case DT_FLAGS_1: +- if (xdh_val == DF_1_PIE) ++ if (xdh_val & DF_1_PIE) + ms->mode |= 0111; + else + ms->mode &= ~0111; +@@ -1611,6 +1611,8 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + switch (xph_type) { + case PT_DYNAMIC: + offset = 0; ++ // Let DF_1 determine if we are PIE or not. ++ ms->mode &= ~0111; + for (;;) { + if (offset >= (size_t)bufsize) + break; +-- +2.39.1 + diff --git a/SOURCES/file-5.33-static-PIE-binaries-4.patch b/SOURCES/file-5.33-static-PIE-binaries-4.patch new file mode 100644 index 0000000..03cf938 --- /dev/null +++ b/SOURCES/file-5.33-static-PIE-binaries-4.patch @@ -0,0 +1,125 @@ +From 948d0e24f33c3b411b5ec1e320acec889e6781b8 Mon Sep 17 00:00:00 2001 +From: Vincent Mihalkovic +Date: Mon, 6 Feb 2023 15:04:33 +0100 +Subject: [PATCH] Improve detection of static-pie binaries, and don't call them + "dynamically linked", but call them "static-pie" linked. + +363d7fcf703ad3ebf37b45693b2c9e43eb8b4176 +--- + src/readelf.c | 35 +++++++++++++++++++++++++---------- + 1 file changed, 25 insertions(+), 10 deletions(-) + +diff --git a/src/readelf.c b/src/readelf.c +index 9c75c0a..0011659 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -1040,7 +1040,7 @@ 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) ++ int clazz, int swap, int *pie, size_t *need) + { + Elf32_Dyn dh32; + Elf64_Dyn dh64; +@@ -1058,11 +1058,15 @@ dodynamic(struct magic_set *ms, void *vbuf, size_t offset, size_t size, + + switch (xdh_tag) { + case DT_FLAGS_1: ++ *pie = 1; + if (xdh_val & DF_1_PIE) + ms->mode |= 0111; + else + ms->mode &= ~0111; + break; ++ case DT_NEEDED: ++ (*need)++; ++ break; + default: + break; + } +@@ -1529,9 +1533,10 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, + } + + /* +- * Look through the program headers of an executable image, searching +- * for a PT_INTERP section; if one is found, it's dynamically linked, +- * otherwise it's statically linked. ++ * Look through the program headers of an executable image, to determine ++ * if it is statically or dynamically linked. If it has a dynamic section, ++ * it is pie, and does not have an interpreter or needed libraries, we ++ * call it static pie. + */ + private int + dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, +@@ -1540,12 +1545,13 @@ 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 *linking_style; + unsigned char nbuf[BUFSIZ]; + char ibuf[BUFSIZ]; + char interp[BUFSIZ]; + ssize_t bufsize; +- size_t offset, align, len; ++ size_t offset, align, len, need = 0; ++ int pie = 0, dynamic = 0; + + if (size != xph_sizeof) { + if (file_printf(ms, ", corrupted program header size") == -1) +@@ -1569,7 +1575,6 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + /* Things we can determine before we seek */ + switch (xph_type) { + case PT_DYNAMIC: +- linking_style = "dynamically"; + doread = 1; + break; + case PT_NOTE: +@@ -1610,6 +1615,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + /* Things we can determine when we seek */ + switch (xph_type) { + case PT_DYNAMIC: ++ dynamic = 1; + offset = 0; + // Let DF_1 determine if we are PIE or not. + ms->mode &= ~0111; +@@ -1617,7 +1623,8 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + if (offset >= (size_t)bufsize) + break; + offset = dodynamic(ms, nbuf, offset, +- CAST(size_t, bufsize), clazz, swap); ++ CAST(size_t, bufsize), clazz, swap, ++ &pie, &need); + if (offset == 0) + break; + } +@@ -1626,6 +1633,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + break; + + case PT_INTERP: ++ need++; + if (ms->flags & MAGIC_MIME) + continue; + if (bufsize && nbuf[0]) { +@@ -1660,8 +1668,15 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + } + if (ms->flags & MAGIC_MIME) + return 0; +- if (file_printf(ms, ", %s linked", linking_style) +- == -1) ++ if (dynamic) { ++ if (pie && need == 0) ++ linking_style = "static-pie"; ++ else ++ linking_style = "dynamically"; ++ } else { ++ linking_style = "statically"; ++ } ++ if (file_printf(ms, ", %s linked", linking_style) == -1) + return -1; + if (interp[0]) + if (file_printf(ms, ", interpreter %s", +-- +2.39.1 + diff --git a/SOURCES/file-5.33-static-PIE-binaries-5.patch b/SOURCES/file-5.33-static-PIE-binaries-5.patch new file mode 100644 index 0000000..6597ac1 --- /dev/null +++ b/SOURCES/file-5.33-static-PIE-binaries-5.patch @@ -0,0 +1,13 @@ +diff --git a/src/readelf.c b/src/readelf.c +index d836e68..6d4b40b 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -69,7 +69,7 @@ toomany(struct magic_set *ms, const char *name, uint16_t num) + { + if (file_printf(ms, ", too many %s (%u)", name, num) == -1) + return -1; +- return 0; ++ return 1; + } + + private uint16_t diff --git a/SPECS/file.spec b/SPECS/file.spec index 9c984c6..001d59a 100644 --- a/SPECS/file.spec +++ b/SPECS/file.spec @@ -15,7 +15,7 @@ Summary: A utility for determining file types Name: file Version: 5.33 -Release: 21%{?dist} +Release: 24%{?dist} License: BSD Group: Applications/File Source0: ftp://ftp.astron.com/pub/file/file-%{version}.tar.gz @@ -88,6 +88,22 @@ Patch22: file-5.37-CVE-2019-18218.patch # not yet upstream (#2095828) Patch23: file-5.33-fix-compression.patch +# upstream commit: 709dfecf25c2eb2822f7e0b8c30d6329cd2d97fb (#2061557) +Patch24: file-5.33-floating-point-exception.patch + +# upstream commit: e2adab1456c2bd8b005ddf8ed71540a37d05cb08 (#2071581) +Patch25: file-5.33-static-PIE-binaries-0.patch +# upstream commit: 9109a696f3289ba00eaa222fd432755ec4287e28 (#2071581) +Patch26: file-5.33-static-PIE-binaries-1.patch +# upstream commit: 9ffbd485ba4647827c4bdacf3a2de690f6765b0c (#2071581) +Patch27: file-5.33-static-PIE-binaries-2.patch +# upstream commit: 03084b161cf888b5286dbbcd964c31ccad4f64d9 (#2071581) +Patch28: file-5.33-static-PIE-binaries-3.patch +# upstream commit: 363d7fcf703ad3ebf37b45693b2c9e43eb8b4176 (#2071581) +Patch29: file-5.33-static-PIE-binaries-4.patch +# upstream commit: 9c3137904e59d68debb97fceaced46a691ba241a (#2071581) +Patch30: file-5.33-static-PIE-binaries-5.patch + URL: http://www.darwinsys.com/file/ Requires: file-libs = %{version}-%{release} BuildRequires: zlib-devel @@ -112,6 +128,7 @@ Libraries for applications using libmagic. Summary: Libraries and header files for file development Group: Applications/File Requires: %{name} = %{version}-%{release} +Requires: file-libs%{?_isa} = %{version}-%{release} %description devel The file-devel package contains the header files and libmagic library @@ -258,6 +275,15 @@ cd %{py3dir} %endif %changelog +* Wed Feb 22 2023 Vincent Mihalkovic - 5.33-24 +- fix detection of static-pie binaries (#2071581) + +* Wed Feb 01 2023 Vincent Mihalkovic - 5.33-23 +- fix detection of static-pie binaries (#2071581) + +* Tue Jan 31 2023 Vincent Mihalkovic - 5.33-22 +- fix issue with libmagic and floating point exceptions (#2061557) + * Wed Aug 17 2022 Vincent Mihalkovic - 5.33-21 - fix recognition (src/compress.c) of compressed empty files (#2095828)