diff -Nru pax-utils-1.2.3/debian/changelog pax-utils-1.2.4/debian/changelog --- pax-utils-1.2.3/debian/changelog 2019-01-12 13:58:52.000000000 +0000 +++ pax-utils-1.2.4/debian/changelog 2019-01-19 14:53:28.000000000 +0000 @@ -1,3 +1,9 @@ +pax-utils (1.2.4-1) unstable; urgency=medium + + * New upstream version 1.2.4 + + -- Tomasz Buchert Sat, 19 Jan 2019 15:53:28 +0100 + pax-utils (1.2.3-3) unstable; urgency=medium * refresh packaging (debhelper 12, std-ver 4.3.0) diff -Nru pax-utils-1.2.3/dumpelf.c pax-utils-1.2.4/dumpelf.c --- pax-utils-1.2.3/dumpelf.c 2018-02-18 20:10:45.000000000 +0000 +++ pax-utils-1.2.4/dumpelf.c 2019-01-14 22:35:29.000000000 +0000 @@ -55,7 +55,7 @@ /* setup the struct to namespace this elf */ #define MAKE_STRUCT(B) \ if (elf->elf_class == ELFCLASS ## B) { \ - Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ + const Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ b = B; \ printf( \ "Elf%1$i_Dyn dumpedelf_dyn_%2$zu[];\n" \ @@ -300,7 +300,7 @@ if (elf->elf_class == ELFCLASS ## B) { \ const Elf ## B ## _Phdr *phdr = PHDR ## B (phdr_void); \ Elf ## B ## _Off offset = EGET(phdr->p_offset); \ - void *vdata = elf->vdata + offset; \ + const void *vdata = elf->vdata + offset; \ uint32_t p_type = EGET(phdr->p_type); \ printf("/* Program Header #%zu 0x%tX */\n{\n", \ phdr_cnt, (uintptr_t)phdr_void - elf->udata); \ @@ -356,7 +356,7 @@ size_t i; /* Make sure the string is valid. */ - if ((void *)section_name >= elf->data_end) + if ((const void *)section_name >= elf->data_end) section_name = ""; else if (memchr(section_name, 0, elf->len - (section_name - elf->data)) == NULL) section_name = ""; @@ -388,8 +388,8 @@ } else if (!VALID_RANGE(elf, offset, size)) { \ printf(" /* corrupt section header ! */ "); \ } else if (size && be_verbose) { \ - void *vdata = elf->vdata + offset; \ - unsigned char *data = vdata; \ + const void *vdata = elf->vdata + offset; \ + const unsigned char *data = vdata; \ switch (type) { \ case SHT_PROGBITS: { \ if (strcmp(section_name, ".interp") == 0) { \ @@ -420,7 +420,7 @@ break; \ } \ case SHT_DYNSYM: { \ - Elf##B##_Sym *sym = vdata; \ + const Elf##B##_Sym *sym = vdata; \ printf("\n\t/%c section dump:\n", '*'); \ if (EGET(shdr->sh_entsize) < sizeof(*sym)) \ printf(" /* corrupt section ! */ "); \ @@ -443,7 +443,7 @@ dump_notes(elf, B, vdata, vdata + EGET(shdr->sh_size)); \ break; \ case SHT_GNU_LIBLIST: { \ - Elf##B##_Lib *lib = vdata; \ + const Elf##B##_Lib *lib = vdata; \ printf("\n\t/%c section dump:\n", '*'); \ if (EGET(shdr->sh_entsize) < sizeof(*lib)) \ printf(" /* corrupt section ! */ "); \ diff -Nru pax-utils-1.2.3/lddtree.py pax-utils-1.2.4/lddtree.py --- pax-utils-1.2.3/lddtree.py 2018-02-18 20:10:45.000000000 +0000 +++ pax-utils-1.2.4/lddtree.py 2019-01-14 22:35:29.000000000 +0000 @@ -122,7 +122,7 @@ try: os.makedirs(path) except OSError as e: - if e.errno != os.errno.EEXIST: + if e.errno != errno.EEXIST: raise diff -Nru pax-utils-1.2.3/Makefile pax-utils-1.2.4/Makefile --- pax-utils-1.2.3/Makefile 2018-02-18 20:10:45.000000000 +0000 +++ pax-utils-1.2.4/Makefile 2019-01-14 22:35:29.000000000 +0000 @@ -2,13 +2,15 @@ # Distributed under the terms of the GNU General Public License v2 #################################################################### -check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; \ +check_compiler = \ + $(shell if $(CC) $(WUNKNOWN) $(1) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ then echo "$(1)"; else echo "$(2)"; fi) -check_gcc_many = $(foreach flag,$(1),$(call check_gcc,$(flag))) +check_compiler_many = $(foreach flag,$(1),$(call check_compiler,$(flag))) #################################################################### # Avoid CC overhead when installing ifneq ($(MAKECMDGOALS),install) +WUNKNOWN := $(call check_compiler,-Werror=unknown-warning-option) _WFLAGS := \ -Wdeclaration-after-statement \ -Wextra \ @@ -19,7 +21,7 @@ -Wmissing-declarations -Wmissing-prototypes -Wwrite-strings \ -Wbad-function-cast -Wnested-externs -Wcomment -Winline \ -Wchar-subscripts -Wcast-align -Wno-format-nonliteral \ - $(call check_gcc_many,$(_WFLAGS)) + $(call check_compiler_many,$(_WFLAGS)) endif CFLAGS ?= -O2 -pipe @@ -86,7 +88,7 @@ -fsanitize=leak \ -fsanitize=undefined debug: clean - $(MAKE) CFLAGS="$(CFLAGS) -g3 -ggdb $(call check_gcc_many,$(DEBUG_FLAGS))" all + $(MAKE) CFLAGS="$(CFLAGS) -g3 -ggdb $(call check_compiler_many,$(DEBUG_FLAGS))" all @-chpax -permsx $(ELF_TARGETS) @-paxctl -permsx $(ELF_TARGETS) diff -Nru pax-utils-1.2.3/paxelf.c pax-utils-1.2.4/paxelf.c --- pax-utils-1.2.3/paxelf.c 2018-02-18 20:10:45.000000000 +0000 +++ pax-utils-1.2.4/paxelf.c 2019-01-14 22:35:29.000000000 +0000 @@ -86,7 +86,7 @@ { 0, 0 } }; -unsigned int get_etype(elfobj *elf) +unsigned int get_etype(const elfobj *elf) { if (elf->elf_class == ELFCLASS32) return EGET(EHDR32(elf->ehdr)->e_type); @@ -94,12 +94,12 @@ return EGET(EHDR64(elf->ehdr)->e_type); } -const char *get_elfetype(elfobj *elf) +const char *get_elfetype(const elfobj *elf) { return find_pairtype(elf_etypes, get_etype(elf)); } -const char *get_endian(elfobj *elf) +const char *get_endian(const elfobj *elf) { switch (elf->data[EI_DATA]) { case ELFDATA2LSB: return "LE"; @@ -109,7 +109,7 @@ } /* translate elf EF_ defines -- tricky as it's based on EM_ */ -static unsigned int get_eflags(elfobj *elf) +static unsigned int get_eflags(const elfobj *elf) { if (elf->elf_class == ELFCLASS32) return EGET(EHDR32(elf->ehdr)->e_flags); @@ -117,7 +117,7 @@ return EGET(EHDR64(elf->ehdr)->e_flags); } -static int arm_eabi_poker(elfobj *elf) +static int arm_eabi_poker(const elfobj *elf) { unsigned int emachine, eflags; @@ -133,7 +133,7 @@ return -1; } -const char *get_elf_eabi(elfobj *elf) +const char *get_elf_eabi(const elfobj *elf) { static char buf[26]; int eabi = arm_eabi_poker(elf); @@ -144,7 +144,7 @@ return buf; } -const char *get_elfosabi(elfobj *elf) +const char *get_elfosabi(const elfobj *elf) { const char *str = get_elfeitype(EI_OSABI, elf->data[EI_OSABI]); if (strncmp(str, "ELFOSABI_", 9) == 0) @@ -279,7 +279,7 @@ { 0, 0 } }; -unsigned int get_emtype(elfobj *elf) +unsigned int get_emtype(const elfobj *elf) { if (elf->elf_class == ELFCLASS32) return EGET(EHDR32(elf->ehdr)->e_machine); @@ -287,7 +287,7 @@ return EGET(EHDR64(elf->ehdr)->e_machine); } -const char *get_elfemtype(elfobj *elf) +const char *get_elfemtype(const elfobj *elf) { return find_pairtype(elf_emtypes, get_emtype(elf)); } @@ -558,7 +558,7 @@ ((buff[EI_CLASS] == ELFCLASS32 || buff[EI_CLASS] == ELFCLASS64) && \ (buff[EI_DATA] == ELFDATA2LSB || buff[EI_DATA] == ELFDATA2MSB) && \ (buff[EI_VERSION] == EV_CURRENT)) -elfobj *readelf_buffer(const char *filename, void *buffer, size_t buffer_len) +elfobj *readelf_buffer(const char *filename, const void *buffer, size_t buffer_len) { elfobj *elf; @@ -616,7 +616,7 @@ #define READELF_HEADER(B) \ if (elf->elf_class == ELFCLASS ## B) { \ char invalid; \ - Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ + const Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ Elf ## B ## _Off size; \ /* verify program header */ \ invalid = 0; \ @@ -720,7 +720,7 @@ /* undo the readelf() stuff */ void unreadelf(elfobj *elf) { - if (elf->is_mmap) munmap(elf->vdata, elf->len); + if (elf->is_mmap) munmap((void *)elf->vdata, elf->len); if (elf->fd != -1) close(elf->fd); if (!__PAX_UNALIGNED_OK) free(elf->_data); free(elf); @@ -784,19 +784,19 @@ return buffer; } -void *elf_findsecbyname(elfobj *elf, const char *name) +const void *elf_findsecbyname(const elfobj *elf, const char *name) { unsigned int i; - char *shdr_name; - void *ret = NULL; + const char *shdr_name; + const void *ret = NULL; if (elf->shdr == NULL) return NULL; #define FINDSEC(B) \ if (elf->elf_class == ELFCLASS ## B) { \ - Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ - Elf ## B ## _Shdr *shdr = SHDR ## B (elf->shdr); \ - Elf ## B ## _Shdr *strtbl; \ + const Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ + const Elf ## B ## _Shdr *shdr = SHDR ## B (elf->shdr); \ + const Elf ## B ## _Shdr *strtbl; \ Elf ## B ## _Off offset; \ uint16_t shstrndx = EGET(ehdr->e_shstrndx); \ uint16_t shnum = EGET(ehdr->e_shnum); \ @@ -808,7 +808,7 @@ shdr_name = elf->data + offset; \ if (!strcmp(shdr_name, name)) { \ if (ret) warnf("Multiple '%s' sections !?", name); \ - ret = (void*)&(shdr[i]); \ + ret = &shdr[i]; \ } \ } } FINDSEC(32) diff -Nru pax-utils-1.2.3/paxelf.h pax-utils-1.2.4/paxelf.h --- pax-utils-1.2.3/paxelf.h 2018-02-18 20:10:45.000000000 +0000 +++ pax-utils-1.2.4/paxelf.h 2019-01-14 22:35:29.000000000 +0000 @@ -12,11 +12,16 @@ #define _PAX_ELF_H typedef struct { - void *phdr; - void *shdr; + const void *phdr; + const void *shdr; + /* When we need to duplicate the ELF buffer for alignment. */ void *_data; - union { void *ehdr, *vdata; char *data; uintptr_t udata; }; - void *data_end; + union { + const void *ehdr, *vdata; + const char *data; + uintptr_t udata; + }; + const void *data_end; char elf_class; off_t len; int fd; @@ -53,18 +58,18 @@ extern const char *pax_short_hf_flags(unsigned long flags); extern const char *pax_short_pf_flags(unsigned long flags); extern const char *gnu_short_stack_flags(unsigned long flags); -extern elfobj *readelf_buffer(const char *filename, void *buffer, size_t buffer_len); +extern elfobj *readelf_buffer(const char *filename, const void *buffer, size_t buffer_len); extern elfobj *_readelf_fd(const char *filename, int fd, size_t len, int read_only); #define readelf_fd(filename, fd, len) _readelf_fd(filename, fd, len, 1) extern elfobj *_readelf(const char *filename, int read_only); #define readelf(filename) _readelf(filename, 1) extern void unreadelf(elfobj *elf); extern const char *get_elfeitype(int ei_type, int type); -extern const char *get_elfetype(elfobj *elf); -extern const char *get_endian(elfobj *elf); -extern const char *get_elfosabi(elfobj *elf); -extern const char *get_elf_eabi(elfobj *elf); -extern const char *get_elfemtype(elfobj *elf); +extern const char *get_elfetype(const elfobj *elf); +extern const char *get_endian(const elfobj *elf); +extern const char *get_elfosabi(const elfobj *elf); +extern const char *get_elf_eabi(const elfobj *elf); +extern const char *get_elfemtype(const elfobj *elf); extern const char *get_elfptype(int type); extern const char *get_elfdtype(int type); extern const char *get_elfshntype(int type); @@ -73,9 +78,9 @@ extern const char *get_elfstvtype(int type); extern const char *get_elfstttype(int type); extern const char *get_elfnttype(uint16_t e_type, const char *name, int type); -extern void *elf_findsecbyname(elfobj *elf, const char *name); -extern unsigned int get_etype(elfobj *elf); -extern unsigned int get_emtype(elfobj *elf); +extern const void *elf_findsecbyname(const elfobj *elf, const char *name); +extern unsigned int get_etype(const elfobj *elf); +extern unsigned int get_emtype(const elfobj *elf); extern void print_etypes(FILE *); extern unsigned int etype_lookup(const char *); diff -Nru pax-utils-1.2.3/paxldso.c pax-utils-1.2.4/paxldso.c --- pax-utils-1.2.3/paxldso.c 2018-02-18 20:10:45.000000000 +0000 +++ pax-utils-1.2.4/paxldso.c 2019-01-14 22:35:29.000000000 +0000 @@ -68,7 +68,7 @@ */ if (elf->elf_class == ELFCLASS32) { - Elf32_Ehdr *ehdr = EHDR32(elf->ehdr); + const Elf32_Ehdr *ehdr = EHDR32(elf->ehdr); switch (EGET(ehdr->e_machine)) { case EM_AARCH64: @@ -101,7 +101,7 @@ break; } } else { - Elf64_Ehdr *ehdr = EHDR64(elf->ehdr); + const Elf64_Ehdr *ehdr = EHDR64(elf->ehdr); switch (EGET(ehdr->e_machine)) { case EM_AARCH64: diff -Nru pax-utils-1.2.3/pspax.c pax-utils-1.2.4/pspax.c --- pax-utils-1.2.3/pspax.c 2018-02-18 20:10:45.000000000 +0000 +++ pax-utils-1.2.4/pspax.c 2019-01-14 22:35:29.000000000 +0000 @@ -75,7 +75,7 @@ return elf; } -static char *get_proc_name_cmdline(int pfd) +static const char *get_proc_name_cmdline(int pfd) { FILE *fp; static char str[1024]; @@ -93,7 +93,7 @@ return (str); } -static char *get_proc_name(int pfd) +static const char *get_proc_name(int pfd) { FILE *fp; static char str[BUFSIZ]; @@ -198,10 +198,10 @@ # define NOTE_TO_SELF #endif -static struct passwd *get_proc_passwd(int pfd) +static const struct passwd *get_proc_passwd(int pfd) { struct stat st; - struct passwd *pwd = NULL; + const struct passwd *pwd = NULL; if (fstatat(pfd, "stat", &st, AT_SYMLINK_NOFOLLOW) != -1) pwd = getpwuid(st.st_uid); @@ -209,7 +209,7 @@ return pwd; } -static char *get_proc_status(int pfd, const char *name) +static const char *get_proc_status(int pfd, const char *name) { FILE *fp; size_t len; @@ -233,7 +233,7 @@ return NULL; } -static char *get_pid_attr(int pfd) +static const char *get_pid_attr(int pfd) { FILE *fp; char *p; @@ -250,7 +250,7 @@ return buf; } -static char *get_pid_addr(int pfd) +static const char *get_pid_addr(int pfd) { FILE *fp; char *p; @@ -281,7 +281,7 @@ return ret; } -static char *scanelf_file_phdr(elfobj *elf) +static const char *scanelf_file_phdr(elfobj *elf) { static char ret[8]; unsigned long i, off, multi_stack, multi_load; @@ -294,8 +294,8 @@ uint32_t flags; #define SHOW_PHDR(B) \ if (elf->elf_class == ELFCLASS ## B) { \ - Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ - Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ + const Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ + const Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \ if (multi_stack++) warnf("%s: multiple PT_GNU_STACK's !?", elf->filename); \ @@ -336,7 +336,7 @@ pid_t pid; pid_t ppid = show_pid; int have_attr, have_addr, wx; - struct passwd *pwd; + const struct passwd *pwd; const char *pax, *type, *name, *attr, *addr; char *caps; int pfd; @@ -375,7 +375,7 @@ continue; if (find_name && pid) { - char *str = get_proc_name(pfd); + const char *str = get_proc_name(pfd); if (!str) goto next_pid; if (strcmp(str, find_name) != 0) @@ -504,8 +504,8 @@ static void parseargs(int argc, char *argv[]) { int flag; - struct passwd *pwd = NULL; - struct group *gwd = NULL; + const struct passwd *pwd = NULL; + const struct group *gwd = NULL; opterr = 0; while ((flag=getopt_long(argc, argv, PARSE_FLAGS, long_opts, NULL)) != -1) { @@ -563,7 +563,7 @@ int main(int argc, char *argv[]) { - char *name = NULL; + const char *name = NULL; /* We unshare pidns but don't actually enter it. That means * we still get to scan /proc, but just not fork children. */ diff -Nru pax-utils-1.2.3/scanelf.c pax-utils-1.2.4/scanelf.c --- pax-utils-1.2.3/scanelf.c 2018-02-18 20:10:45.000000000 +0000 +++ pax-utils-1.2.4/scanelf.c 2019-01-14 22:35:29.000000000 +0000 @@ -150,8 +150,8 @@ #define FIND_PT_TYPE(B) \ size_t i; \ - Elf##B##_Ehdr *ehdr = EHDR ## B (elf->ehdr); \ - Elf##B##_Phdr *phdr = PHDR ## B (elf->phdr); \ + const Elf##B##_Ehdr *ehdr = EHDR ## B (elf->ehdr); \ + const Elf##B##_Phdr *phdr = PHDR ## B (elf->phdr); \ \ for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ if (EGET(phdr[i].p_type) != p_type) \ @@ -168,14 +168,14 @@ return ret; } -static void *scanelf_file_get_pt_dynamic(elfobj *elf) +static const void *scanelf_file_get_pt_dynamic(elfobj *elf) { ssize_t i = scanelf_file_find_phdr(elf, PT_DYNAMIC); if (i == -1) return NULL; #define CHECK_PT_DYNAMIC(B) \ - Elf##B##_Phdr *phdr = &PHDR##B(elf->phdr)[i]; \ + const Elf##B##_Phdr *phdr = &PHDR##B(elf->phdr)[i]; \ Elf##B##_Off offset; \ \ if (EGET(phdr->p_filesz) == 0) \ @@ -191,23 +191,23 @@ #define scanelf_dt_for_each(B, elf, dyn) \ { \ - Elf##B##_Phdr *_phdr = scanelf_file_get_pt_dynamic(elf); \ + const Elf##B##_Phdr *_phdr = scanelf_file_get_pt_dynamic(elf); \ dyn = (_phdr == NULL) ? elf->data_end : DYN##B(elf->vdata + EGET(_phdr->p_offset)); \ } \ --dyn; \ while ((void *)++dyn < elf->data_end - sizeof(*dyn) && EGET(dyn->d_tag) != DT_NULL) /* sub-funcs for scanelf_fileat() */ -static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **str) +static void scanelf_file_get_symtabs(elfobj *elf, const void **sym, const void **str) { /* find the best SHT_DYNSYM and SHT_STRTAB sections */ /* debug sections */ - void *symtab = elf_findsecbyname(elf, ".symtab"); - void *strtab = elf_findsecbyname(elf, ".strtab"); + const void *symtab = elf_findsecbyname(elf, ".symtab"); + const void *strtab = elf_findsecbyname(elf, ".strtab"); /* runtime sections */ - void *dynsym = elf_findsecbyname(elf, ".dynsym"); - void *dynstr = elf_findsecbyname(elf, ".dynstr"); + const void *dynsym = elf_findsecbyname(elf, ".dynsym"); + const void *dynstr = elf_findsecbyname(elf, ".dynstr"); /* * If the sections are marked NOBITS, then they don't exist, so we just @@ -219,10 +219,10 @@ * as they are generated in sync. Trying to mix them won't work. */ #define GET_SYMTABS(B) \ - Elf ## B ## _Shdr *esymtab = symtab; \ - Elf ## B ## _Shdr *estrtab = strtab; \ - Elf ## B ## _Shdr *edynsym = dynsym; \ - Elf ## B ## _Shdr *edynstr = dynstr; \ + const Elf ## B ## _Shdr *esymtab = symtab; \ + const Elf ## B ## _Shdr *estrtab = strtab; \ + const Elf ## B ## _Shdr *edynsym = dynsym; \ + const Elf ## B ## _Shdr *edynstr = dynstr; \ \ if (!VALID_SHDR(elf, esymtab)) \ symtab = NULL; \ @@ -265,10 +265,10 @@ #define GET_SYMTABS_DT(B) \ size_t i; \ static Elf ## B ## _Shdr sym_shdr, str_shdr; \ - Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ - Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ + const Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ + const Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ Elf ## B ## _Addr vsym, vstr, vhash, vgnu_hash; \ - Elf ## B ## _Dyn *dyn; \ + const Elf ## B ## _Dyn *dyn; \ \ /* lookup symbols used at runtime with DT_SYMTAB / DT_STRTAB */ \ vsym = vstr = vhash = vgnu_hash = 0; \ @@ -307,11 +307,11 @@ if (vhash >= vaddr && vhash < vaddr + filesz) { \ /* Scan the hash table to see how many entries we have */ \ Elf32_Word max_sym_idx = 0; \ - Elf32_Word *hashtbl = elf->vdata + hash_offset; \ + const Elf32_Word *hashtbl = elf->vdata + hash_offset; \ Elf32_Word b, nbuckets = EGET(hashtbl[0]); \ Elf32_Word nchains = EGET(hashtbl[1]); \ - Elf32_Word *buckets = &hashtbl[2]; \ - Elf32_Word *chains = &buckets[nbuckets]; \ + const Elf32_Word *buckets = &hashtbl[2]; \ + const Elf32_Word *chains = &buckets[nbuckets]; \ Elf32_Word sym_idx; \ Elf32_Word chained; \ \ @@ -337,14 +337,14 @@ } \ \ if (vsym >= vaddr && vsym < vaddr + filesz) { \ - Elf##B##_Shdr *shdr = &sym_shdr; \ + const Elf##B##_Shdr *shdr = &sym_shdr; \ ESET(sym_shdr.sh_offset, offset + (vsym - vaddr)); \ if (VALID_SHDR(elf, shdr)) \ *sym = shdr; \ } \ \ if (vstr >= vaddr && vstr < vaddr + filesz) { \ - Elf##B##_Shdr *shdr = &str_shdr; \ + const Elf##B##_Shdr *shdr = &str_shdr; \ ESET(str_shdr.sh_offset, offset + (vstr - vaddr)); \ if (VALID_SHDR(elf, shdr)) \ *str = shdr; \ @@ -369,14 +369,15 @@ memset(&ret, 0, sizeof(ret)); #define SHOW_PAX(B) \ - Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ - Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ + const Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ + const Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ if (EGET(phdr[i].p_type) != PT_PAX_FLAGS) \ continue; \ if (fix_elf && setpax) { \ /* set the paxctl flags */ \ - ESET(phdr[i].p_flags, setpax); \ + Elf ## B ## _Phdr *wphdr = (void *)&phdr[i]; \ + ESET(wphdr->p_flags, setpax); \ } \ if (be_quiet && (EGET(phdr[i].p_flags) == (PF_NOEMUTRAMP | PF_NORANDEXEC))) \ continue; \ @@ -411,7 +412,7 @@ return ret; } -static char *scanelf_file_phdr(elfobj *elf, char *found_phdr, char *found_relro, char *found_load) +static const char *scanelf_file_phdr(elfobj *elf, char *found_phdr, char *found_relro, char *found_load) { static char ret[12]; char *found; @@ -426,11 +427,11 @@ #define NOTE_GNU_STACK ".note.GNU-stack" #define SHOW_PHDR(B) \ - Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ + const Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ Elf ## B ## _Off offset; \ uint32_t flags, check_flags; \ if (elf->phdr != NULL) { \ - Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ + const Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ for (i = 0; i < EGET(ehdr->e_phnum); ++i) { \ if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \ if (multi_stack++) \ @@ -458,7 +459,8 @@ if (be_quiet && ((flags & check_flags) != check_flags)) \ continue; \ if ((EGET(phdr[i].p_type) != PT_LOAD) && (fix_elf && ((flags & PF_X) != flags))) { \ - ESET(phdr[i].p_flags, flags & (PF_X ^ (size_t)-1)); \ + Elf ## B ## _Phdr *wphdr = (void *)&phdr[i]; \ + ESET(wphdr->p_flags, flags & (PF_X ^ (size_t)-1)); \ ret[3] = ret[7] = '!'; \ flags = EGET(phdr[i].p_flags); \ } \ @@ -468,9 +470,9 @@ } \ } else if (elf->shdr != NULL) { \ /* no program headers which means this is prob an object file */ \ - Elf ## B ## _Shdr *shdr = SHDR ## B (elf->shdr); \ + const Elf ## B ## _Shdr *shdr = SHDR ## B (elf->shdr); \ uint16_t shstrndx = EGET(ehdr->e_shstrndx); \ - Elf ## B ## _Shdr *strtbl = shdr + shstrndx; \ + const Elf ## B ## _Shdr *strtbl = shdr + shstrndx; \ uint16_t shnum = EGET(ehdr->e_shnum); \ if (shstrndx >= shnum || !VALID_SHDR(elf, strtbl)) \ goto corrupt_shdr; \ @@ -533,7 +535,7 @@ if (file_matches_list(elf->filename, qa_textrels)) return NULL; #define SHOW_TEXTREL(B) \ - Elf ## B ## _Dyn *dyn; \ + const Elf ## B ## _Dyn *dyn; \ \ scanelf_dt_for_each(B, elf, dyn) { \ if (EGET(dyn->d_tag) == DT_TEXTREL) { /*dyn->d_tag != DT_FLAGS)*/ \ @@ -556,10 +558,10 @@ * Should rewrite this to check PT_LOAD sections that are marked * Executable rather than the section named '.text'. */ -static char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char *found_textrel) +static const char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char *found_textrel) { unsigned long r, rmax; - void *symtab_void, *strtab_void; + const void *symtab_void, *strtab_void; if (!show_textrels) return NULL; @@ -571,13 +573,13 @@ #define SHOW_TEXTRELS(B) \ size_t i; \ - Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ - Elf ## B ## _Phdr *phdr; \ - Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \ - Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ - Elf ## B ## _Rel *rel; \ - Elf ## B ## _Rela *rela; \ - Elf ## B ## _Dyn *dyn, *drel, *drelsz, *drelent, *dpltrel; \ + const Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ + const Elf ## B ## _Phdr *phdr; \ + const Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \ + const Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ + const Elf ## B ## _Rel *rel; \ + const Elf ## B ## _Rela *rela; \ + const Elf ## B ## _Dyn *dyn, *drel, *drelsz, *drelent, *dpltrel; \ uint32_t pltrel; \ Elf ## B ## _Addr load_address = 0; \ Elf ## B ## _Addr file_offset; \ @@ -669,8 +671,8 @@ for (r = 0; r < rmax; ++r) { \ unsigned long sym_max; \ Elf ## B ## _Addr offset_tmp; \ - Elf ## B ## _Sym *func; \ - Elf ## B ## _Sym *sym; \ + const Elf ## B ## _Sym *func; \ + const Elf ## B ## _Sym *sym; \ Elf ## B ## _Addr r_offset; \ uint ## B ## _t r_info; \ if (pltrel == DT_REL) { \ @@ -733,19 +735,21 @@ if (be_verbose && objdump) { \ Elf ## B ## _Addr end_addr = offset_tmp + EGET(func->st_size); \ char *sysbuf; \ - size_t syslen; \ - const char sysfmt[] = "%s -r -R -d -w -l --start-address=0x%lX --stop-address=0x%lX %s | grep --color -i -C 3 '.*[[:space:]]%lX:[[:space:]]*R_.*'\n"; \ - syslen = sizeof(sysfmt) + strlen(objdump) + strlen(elf->filename) + 3 * sizeof(unsigned long) + 1; \ - sysbuf = xmalloc(syslen); \ + int ret; \ if (end_addr < r_offset) \ /* not uncommon when things are optimized out */ \ end_addr = r_offset + 0x100; \ - snprintf(sysbuf, syslen, sysfmt, \ + ret = asprintf( \ + &sysbuf, \ + "%s -r -R -d -w -l --start-address=0x%lX --stop-address=0x%lX %s | " \ + "grep --color -i -C 3 '.*[[:space:]]%lX:[[:space:]]*R_.*'\n", \ objdump, \ (unsigned long)offset_tmp, \ (unsigned long)end_addr, \ elf->filename, \ (unsigned long)r_offset); \ + if (ret < 0) \ + errp("asprintf() failed"); \ fflush(stdout); \ if (system(sysbuf)) {/* don't care */} \ fflush(stdout); \ @@ -761,7 +765,7 @@ return NULL; } -static void rpath_security_checks(elfobj *elf, char *item, const char *dt_type) +static void rpath_security_checks(elfobj *elf, const char *item, const char *dt_type) { struct stat st; switch (*item) { @@ -788,8 +792,8 @@ } static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_t *ret_len) { - char *rpath, *runpath, **r; - void *strtab_void; + const char *rpath, *runpath, **r; + const void *strtab_void; if (!show_rpath) return; @@ -802,8 +806,8 @@ rpath = runpath = NULL; #define SHOW_RPATH(B) \ - Elf ## B ## _Dyn *dyn; \ - Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ + const Elf ## B ## _Dyn *dyn; \ + const Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ Elf ## B ## _Off offset; \ Elf ## B ## _Xword word; \ \ @@ -828,7 +832,7 @@ /* If quiet, don't output paths in ld.so.conf */ \ if (be_quiet) { \ size_t len; \ - char *start, *end; \ + const char *start, *end; \ /* note that we only 'chop' off leading known paths. */ \ /* since *r is read-only memory, we can only move the ptr forward. */ \ start = *r; \ @@ -859,17 +863,21 @@ if (*r) { \ if (fix_elf > 2 || (fix_elf && **r == '\0')) { \ /* just nuke it */ \ - nuke_it##B: \ - memset(*r, 0x00, offset); \ + nuke_it##B: { \ + /* We have to cast away the const. \ + * We know we mapped the backing memory as writable. */ \ + Elf ## B ## _Dyn *wdyn = (void *)dyn; \ + memset((void *)*r, 0x00, offset); \ *r = NULL; \ - ESET(dyn->d_tag, DT_DEBUG); \ - ESET(dyn->d_un.d_ptr, 0); \ + ESET(wdyn->d_tag, DT_DEBUG); \ + ESET(wdyn->d_un.d_ptr, 0); \ + } \ } else if (fix_elf) { \ /* try to clean "bad" paths */ \ size_t len, tmpdir_len; \ char *start, *end; \ const char *tmpdir; \ - start = *r; \ + start = (void *)*r; \ tmpdir = (getenv("TMPDIR") ? : "."); \ tmpdir_len = strlen(tmpdir); \ while (1) { \ @@ -939,8 +947,8 @@ static const char *scanelf_file_needed_lib(elfobj *elf, char *found_needed, char *found_lib, int op, char **ret, size_t *ret_len) { - char *needed; - void *strtab_void; + const char *needed; + const void *strtab_void; char *p; /* @@ -958,8 +966,8 @@ strtab_void = elf_findsecbyname(elf, ".dynstr"); #define SHOW_NEEDED(B) \ - Elf ## B ## _Dyn *dyn; \ - Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ + const Elf ## B ## _Dyn *dyn; \ + const Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ size_t matched = 0; \ \ /* Walk all the dynamic tags to find NEEDED entries */ \ @@ -1011,7 +1019,7 @@ return NULL; } -static char *scanelf_file_interp(elfobj *elf, char *found_interp) +static const char *scanelf_file_interp(elfobj *elf, char *found_interp) { uint64_t offset = 0; @@ -1021,8 +1029,8 @@ /* Walk all the program headers to find the PT_INTERP */ #define GET_PT_INTERP(B) \ size_t i; \ - Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ - Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ + const Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ + const Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ for (i = 0; i < EGET(ehdr->e_phnum); ++i) { \ if (EGET(phdr[i].p_type) == PT_INTERP) { \ offset = EGET(phdr[i].p_offset); \ @@ -1032,10 +1040,10 @@ SCANELF_ELF_SIZED(GET_PT_INTERP); } else if (elf->shdr) { /* Use the section headers to find it */ - void *section = elf_findsecbyname(elf, ".interp"); + const void *section = elf_findsecbyname(elf, ".interp"); #define GET_INTERP(B) \ - Elf ## B ## _Shdr *shdr = SHDR ## B (section); \ + const Elf ## B ## _Shdr *shdr = SHDR ## B (section); \ offset = EGET(shdr->sh_offset); if (section) SCANELF_ELF_SIZED(GET_INTERP); @@ -1043,7 +1051,7 @@ /* Validate the pointer even if we don't use it in output */ if (offset && offset <= (uint64_t)elf->len) { - char *interp = elf->data + offset; + const char *interp = elf->data + offset; /* If it isn't a C pointer, it's garbage */ if (memchr(interp, 0, elf->len - offset)) { @@ -1064,7 +1072,7 @@ if (!elf->phdr) return NULL; #define SHOW_BIND(B) \ - Elf ## B ## _Dyn *dyn; \ + const Elf ## B ## _Dyn *dyn; \ \ scanelf_dt_for_each(B, elf, dyn) { \ dynamic = true; \ @@ -1088,10 +1096,10 @@ return dynamic ? "LAZY" : "STATIC"; } } -static char *scanelf_file_soname(elfobj *elf, char *found_soname) +static const char *scanelf_file_soname(elfobj *elf, char *found_soname) { - char *soname; - void *strtab_void; + const char *soname; + const void *strtab_void; if (!show_soname) return NULL; @@ -1103,9 +1111,9 @@ strtab_void = elf_findsecbyname(elf, ".dynstr"); #define SHOW_SONAME(B) \ - Elf ## B ## _Dyn *dyn; \ - Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ - Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ + const Elf ## B ## _Dyn *dyn; \ + const Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ + const Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ \ /* only look for soname in shared objects */ \ if (EGET(ehdr->e_type) != ET_DYN) \ @@ -1296,7 +1304,7 @@ static char *scanelf_file_sym(elfobj *elf, char *found_sym) { char *ret; - void *symtab_void, *strtab_void; + const void *symtab_void, *strtab_void; if (!find_sym) return NULL; ret = NULL; @@ -1304,11 +1312,11 @@ scanelf_file_get_symtabs(elf, &symtab_void, &strtab_void); #define FIND_SYM(B) \ - Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \ - Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ - Elf ## B ## _Sym *sym = SYM ## B (elf->vdata + EGET(symtab->sh_offset)); \ + const Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \ + const Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ + const Elf ## B ## _Sym *sym = SYM ## B (elf->vdata + EGET(symtab->sh_offset)); \ Elf ## B ## _Word i, cnt = EGET(symtab->sh_entsize); \ - char *symname; \ + const char *symname; \ size_t ret_len = 0; \ if (cnt) \ cnt = EGET(symtab->sh_size) / cnt; \ @@ -1365,7 +1373,7 @@ size_t matched, n; \ int invert; \ const char *section_name; \ - Elf ## B ## _Shdr *section; \ + const Elf ## B ## _Shdr *section; \ \ matched = 0; \ array_for_each(find_section_arr, n, section_name) { \ diff -Nru pax-utils-1.2.3/security.c pax-utils-1.2.4/security.c --- pax-utils-1.2.3/security.c 2018-02-18 20:10:45.000000000 +0000 +++ pax-utils-1.2.4/security.c 2019-01-14 22:35:29.000000000 +0000 @@ -162,6 +162,12 @@ SCMP_SYS(msgsnd), SCMP_SYS(semget), SCMP_SYS(semop), + /* + * Some targets like ppc and i386 implement the above + * syscall as subcalls via ipc() syscall. + * https://bugs.gentoo.org/675378 + */ + SCMP_SYS(ipc), }; int fork_syscalls[] = { SCMP_SYS(clone),