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) { \

Reply via email to