commit: 7853dba4ac9405793cc5275fd38c722b1cba2978 Author: Mike Frysinger <vapier <AT> gentoo <DOT> org> AuthorDate: Sat Mar 4 21:36:29 2017 +0000 Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org> CommitDate: Thu Jun 7 14:05:50 2018 +0000 URL: https://gitweb.gentoo.org/proj/pax-utils.git/commit/?id=7853dba4
paxelf: constify elfobj pointers We rarely need to modify the memory from our input ELFs, so constify all the buffers. We end up having to cast away the const in the "fix" paths in scanelf (which is a bit ugly), but otherwise everything else works. paxelf.c | 4 ++-- paxelf.h | 15 ++++++++++----- scanelf.c | 30 ++++++++++++++++++------------ 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/paxelf.c b/paxelf.c index 59f50fd..dea3757 100644 --- a/paxelf.c +++ b/paxelf.c @@ -558,7 +558,7 @@ const char *get_elfnttype(uint16_t e_type, const char *name, int type) ((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; @@ -720,7 +720,7 @@ elfobj *_readelf(const char *filename, int read_only) /* 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); diff --git a/paxelf.h b/paxelf.h index 0742c40..f252969 100644 --- a/paxelf.h +++ b/paxelf.h @@ -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,7 +58,7 @@ typedef struct { 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); diff --git a/scanelf.c b/scanelf.c index 7936e3c..440a193 100644 --- a/scanelf.c +++ b/scanelf.c @@ -370,13 +370,14 @@ static const char *scanelf_file_pax(elfobj *elf, char *found_pax) #define SHOW_PAX(B) \ const Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ - 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_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; \ @@ -430,7 +431,7 @@ static const char *scanelf_file_phdr(elfobj *elf, char *found_phdr, char *found_ 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 @@ static const char *scanelf_file_phdr(elfobj *elf, char *found_phdr, char *found_ 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); \ } \ @@ -790,7 +792,7 @@ static void rpath_security_checks(elfobj *elf, const char *item, const char *dt_ } static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_t *ret_len) { - char *rpath, *runpath, **r; + const char *rpath, *runpath, **r; const void *strtab_void; if (!show_rpath) return; @@ -804,7 +806,7 @@ static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_ rpath = runpath = NULL; #define SHOW_RPATH(B) \ - Elf ## B ## _Dyn *dyn; \ + const Elf ## B ## _Dyn *dyn; \ const Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ Elf ## B ## _Off offset; \ Elf ## B ## _Xword word; \ @@ -830,7 +832,7 @@ static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_ /* 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; \ @@ -861,17 +863,21 @@ static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_ 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) { \