aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHoward Mao <zhehao.mao@gmail.com>2016-09-21 11:39:08 -0700
committerAndrew Waterman <waterman@eecs.berkeley.edu>2016-09-21 11:39:08 -0700
commitf81b722bf004177eadaf6f1b4b9e699e20257521 (patch)
tree23199e93aa7b88ad6b11e19b359d4f477f2c54b5
parentf892b43a2bb1c2405b9941aaefdb25e3b4efe1f1 (diff)
downloadriscv-pk-f81b722bf004177eadaf6f1b4b9e699e20257521.zip
riscv-pk-f81b722bf004177eadaf6f1b4b9e699e20257521.tar.gz
riscv-pk-f81b722bf004177eadaf6f1b4b9e699e20257521.tar.bz2
make sure pages for ELF sections have correct protection (#40)
-rw-r--r--pk/elf.c18
-rw-r--r--pk/elf.h4
2 files changed, 20 insertions, 2 deletions
diff --git a/pk/elf.c b/pk/elf.c
index ba2dd1d..d0cf8a7 100644
--- a/pk/elf.c
+++ b/pk/elf.c
@@ -10,6 +10,19 @@
#include <elf.h>
#include <string.h>
+/**
+ * The protection flags are in the p_flags section of the program header.
+ * But rather annoyingly, they are the reverse of what mmap expects.
+ */
+static inline int get_prot(uint32_t p_flags)
+{
+ int prot_x = (p_flags & PF_X) ? PROT_EXEC : PROT_NONE;
+ int prot_w = (p_flags & PF_W) ? PROT_WRITE : PROT_NONE;
+ int prot_r = (p_flags & PF_R) ? PROT_READ : PROT_NONE;
+
+ return (prot_x | prot_w | prot_r);
+}
+
void load_elf(const char* fn, elf_info* info)
{
file_t* file = file_open(fn, O_RDONLY, 0);
@@ -60,12 +73,13 @@ void load_elf(const char* fn, elf_info* info)
if (vaddr + ph[i].p_memsz > info->brk_min)
info->brk_min = vaddr + ph[i].p_memsz;
int flags2 = flags | (prepad ? MAP_POPULATE : 0);
- if (__do_mmap(vaddr - prepad, ph[i].p_filesz + prepad, -1, flags2, file, ph[i].p_offset - prepad) != vaddr - prepad)
+ int prot = get_prot(ph[i].p_flags);
+ if (__do_mmap(vaddr - prepad, ph[i].p_filesz + prepad, prot, flags2, file, ph[i].p_offset - prepad) != vaddr - prepad)
goto fail;
memset((void*)vaddr - prepad, 0, prepad);
size_t mapped = ROUNDUP(ph[i].p_filesz + prepad, RISCV_PGSIZE) - prepad;
if (ph[i].p_memsz > mapped)
- if (__do_mmap(vaddr + mapped, ph[i].p_memsz - mapped, -1, flags|MAP_ANONYMOUS, 0, 0) != vaddr + mapped)
+ if (__do_mmap(vaddr + mapped, ph[i].p_memsz - mapped, prot, flags|MAP_ANONYMOUS, 0, 0) != vaddr + mapped)
goto fail;
}
}
diff --git a/pk/elf.h b/pk/elf.h
index c3fa1c3..692a6b5 100644
--- a/pk/elf.h
+++ b/pk/elf.h
@@ -36,6 +36,10 @@
#define AT_SECURE 23
#define AT_RANDOM 25
+#define PF_X 1
+#define PF_W 2
+#define PF_R 4
+
typedef struct {
uint8_t e_ident[16];
uint16_t e_type;