aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2017-03-04 13:36:29 -0800
committerMike Frysinger <vapier@gentoo.org>2018-06-07 10:05:50 -0400
commit7853dba4ac9405793cc5275fd38c722b1cba2978 (patch)
treef6ee148489e76bc3ceee3f525cf4767055b3cd14
parentscanelf: add general const markings to Elf pointers (diff)
downloadpax-utils-7853dba4ac9405793cc5275fd38c722b1cba2978.tar.gz
pax-utils-7853dba4ac9405793cc5275fd38c722b1cba2978.tar.bz2
pax-utils-7853dba4ac9405793cc5275fd38c722b1cba2978.zip
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.
-rw-r--r--paxelf.c4
-rw-r--r--paxelf.h15
-rw-r--r--scanelf.c30
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) { \