Skip to content

Commit

Permalink
Add test for modifying code that was just run
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed May 27, 2018
1 parent 75e8d35 commit 2748b8a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 1 deletion.
2 changes: 1 addition & 1 deletion tests/looper.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#define nop() __asm__ volatile("")

int main() {
int loops = 10000000;
int loops = 100000000;
printf("looping %d times\n", loops);
for (int i = 0; i < loops; i++)
nop();
Expand Down
3 changes: 3 additions & 0 deletions tests/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ executable('forkexec', ['forkexec.c'])

executable('thread', ['thread.c'], dependencies: dependency('threads'))

# various tests for code that modifies itself
executable('modify', ['modify.c'], link_args: ['-zexecstack'])

# qemu test program
executable('qemu-test', ['qemu-test.c'], link_args: ['-lm'])

Expand Down
42 changes: 42 additions & 0 deletions tests/modify.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <setjmp.h>
#include <signal.h>

static char code[] = {
0xb8, 0x01, 0x00, 0x00, 0x00, // movl $1, %eax
0xc3, // ret
};

static sigjmp_buf env;
static int catching = 0;
static void handle_segfault(int sig) {
if (catching) {
catching = 0;
siglongjmp(env, 1);
}
}

static void test(char *code, const char *name) {
printf("%-6s before: %d expected 1\n", name, ((int (*)()) code)());
code[1] = 2;
printf("%-6s after: %d expected 2\n", name, ((int (*)()) code)());
}

int main() {
signal(SIGSEGV, handle_segfault);
void *code_copy = mmap(NULL, 0x1000, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
memcpy(code_copy, code, sizeof(code));

test(code, "static");
test(code_copy, "mmap");
munmap(code_copy, 0x1000);
printf("call nonexistent: ");
catching = 1;
if (!sigsetjmp(env, 1))
printf("%d expected segfault\n", ((int (*)()) code_copy)());
else
printf("segfault\n");
return 0;
}

0 comments on commit 2748b8a

Please sign in to comment.