Permalink
Browse files

elf: make offset pages writeable

This fixes crashes with eager GOT population, where the interpreter
makes the table read-only when done.
  • Loading branch information...
Snaipe committed Dec 23, 2018
1 parent b1290b2 commit 7681d1ee8e0bffff806751092947648a6bebff24
Showing with 22 additions and 0 deletions.
  1. +12 −0 src/plt-elf.c
  2. +9 −0 src/vitals.c
  3. +1 −0 src/vitals.h
@@ -32,6 +32,8 @@
#include "trampoline.h"
#include "vitals.h"

#include <sys/mman.h>

#if MMK_BITS == 32
typedef Elf32_Word ElfWord;
typedef Elf32_Sword ElfSWord;
@@ -272,11 +274,21 @@ plt_offset *plt_get_offsets(plt_ctx ctx, plt_lib lib, const char *name, size_t *
return NULL;
}

#define align2_down(v, d) ((v) & ~((d) - 1))

void plt_set_offsets(plt_offset *offset, size_t nb_off, plt_fn *newval)
{
for (size_t i = 0; i < nb_off; ++i) {
if (!offset[i].oldval)
offset[i].oldval = *offset[i].offset;
void *page_start = (void *)align2_down((uintptr_t)offset[i].offset, 4096);

/* making a page in a rx segment rwx is usually very bad practice,
but this is a test context, we don't have to care as much.
Implementing this right assumes that we have a way to know
the protection of an existing page, which is not necessarily
available on all unices. */
mmk_mprotect(page_start, 4096, PROT_READ|PROT_WRITE|PROT_EXEC);
*offset[i].offset = newval;
}
}
@@ -98,6 +98,12 @@ int mmk_isspace(int c)
return c == ' ' || c == '\t' || c == '\r' || c == '\n';
}

int (*mmk_mprotect_)(void *, size_t, int);
int mmk_mprotect(void *addr, size_t len, int prot)
{
return mmk_mprotect_(addr, len, prot);
}

void *(*mmk_malloc_)(size_t);
void *mmk_malloc(size_t size)
{
@@ -190,4 +196,7 @@ void mmk_init_vital_functions(plt_ctx ctx)
INIT_VITAL_FUNC(malloc);
INIT_VITAL_FUNC(realloc);
INIT_VITAL_FUNC(free);
#ifdef MMK_EXE_FMT_ELF
INIT_VITAL_FUNC(mprotect);
#endif
}
@@ -40,6 +40,7 @@ char *mmk_strcpy(char *dst, const char *src);
char *mmk_strncpy(char *dst, const char *src, size_t n);
size_t mmk_strlen(const char *s);
int mmk_isspace(int c);
int mmk_mprotect(void *addr, size_t len, int prot);

mmk_noreturn void mmk_panic(const char *, ...);

0 comments on commit 7681d1e

Please sign in to comment.