| Index: tests/dynamic_code_loading/dynamic_modify_test.c
|
| ===================================================================
|
| --- tests/dynamic_code_loading/dynamic_modify_test.c (revision 4097)
|
| +++ tests/dynamic_code_loading/dynamic_modify_test.c (working copy)
|
| @@ -7,6 +7,7 @@
|
| #include <assert.h>
|
| #include <errno.h>
|
| #include <stdio.h>
|
| +#include <stdint.h>
|
| #include <stdlib.h>
|
| #include <string.h>
|
| #include <sys/mman.h>
|
| @@ -14,7 +15,14 @@
|
| #include <sys/nacl_syscalls.h>
|
|
|
| #include "native_client/tests/dynamic_code_loading/templates.h"
|
| +#include "native_client/tests/inbrowser_test_runner/test_runner.h"
|
|
|
| +#if defined(__x86_64__)
|
| +#define BUF_SIZE 64
|
| +#else
|
| +#define BUF_SIZE 32
|
| +#endif
|
| +
|
| #define NACL_BUNDLE_SIZE 32
|
| /*
|
| * TODO(bsy): get this value from the toolchain. Get the toolchain
|
| @@ -31,13 +39,36 @@
|
| nacl.scons, passed via --section-start. */
|
| #define DYNAMIC_CODE_SEGMENT_END 0x1000000
|
|
|
| +struct code_section {
|
| + char *name;
|
| + char *start;
|
| + char *end;
|
| +};
|
|
|
| -char *next_addr = (char *) DYNAMIC_CODE_SEGMENT_START;
|
| +struct code_section illegal_code_sections[] = {
|
| + { "misaligned_replacement",
|
| + &template_func_misaligned_replacement,
|
| + &template_func_misaligned_replacement_end },
|
| + { "illegal_register_replacement",
|
| + &template_func_illegal_register_replacement,
|
| + &template_func_illegal_register_replacement_end },
|
| + { "illegal_guard_replacement",
|
| + &template_func_illegal_guard_replacement,
|
| + &template_func_illegal_guard_replacement_end },
|
| + { "illegal_call_target",
|
| + &template_func_illegal_call_target,
|
| + &template_func_illegal_call_target_end },
|
| + { "illegal_constant_replacement",
|
| + &template_func_illegal_constant_replacement,
|
| + &template_func_illegal_constant_replacement_end },
|
| +};
|
|
|
| -char *allocate_code_space(int pages) {
|
| - char *addr = next_addr;
|
| +uint8_t *next_addr = (uint8_t *) DYNAMIC_CODE_SEGMENT_START;
|
| +
|
| +uint8_t *allocate_code_space(int pages) {
|
| + uint8_t *addr = next_addr;
|
| next_addr += 0x10000 * pages;
|
| - assert(next_addr < (char *) DYNAMIC_CODE_SEGMENT_END);
|
| + assert(next_addr < (uint8_t *) DYNAMIC_CODE_SEGMENT_END);
|
| return addr;
|
| }
|
|
|
| @@ -72,7 +103,7 @@
|
| const char *fragment_end) {
|
| int fragment_size = fragment_end - fragment_start;
|
| assert(dest_size % 32 == 0);
|
| - assert(fragment_size < dest_size);
|
| + assert(fragment_size <= dest_size);
|
| fill_nops(dest, dest_size);
|
| memcpy(dest, fragment_start, fragment_size);
|
| }
|
| @@ -80,7 +111,7 @@
|
| /* Check that we can't dynamically rewrite code. */
|
| void test_replacing_code() {
|
| uint8_t *load_area = allocate_code_space(1);
|
| - uint8_t buf[32];
|
| + uint8_t buf[BUF_SIZE];
|
| int rc;
|
| int (*func)();
|
|
|
| @@ -105,7 +136,7 @@
|
| /* Check that we can dynamically rewrite code. */
|
| void test_replacing_code_unaligned() {
|
| uint8_t *load_area = allocate_code_space(1);
|
| - uint8_t buf[32];
|
| + uint8_t buf[BUF_SIZE];
|
| int first_diff = 0;
|
| int rc;
|
| int (*func)();
|
| @@ -117,14 +148,13 @@
|
| rc = func();
|
| assert(rc == 1234);
|
|
|
| -
|
| /* write replacement to the same location, unaligned */
|
| copy_and_pad_fragment(buf, sizeof(buf), &template_func_replacement,
|
| &template_func_replacement_end);
|
| while (buf[first_diff] == load_area[first_diff] && first_diff < sizeof buf) {
|
| first_diff++;
|
| }
|
| - assert(first_diff>0);
|
| + assert(first_diff > 0 && first_diff <= sizeof(buf));
|
| rc = nacl_dyncode_modify(load_area+first_diff, buf+first_diff,
|
| sizeof(buf)-first_diff);
|
| assert(rc == 0);
|
| @@ -136,8 +166,7 @@
|
| /* Check that we can dynamically delete code. */
|
| void test_deleting_code() {
|
| uint8_t *load_area = allocate_code_space(1);
|
| - uint8_t buf[32];
|
| - int first_diff = 0;
|
| + uint8_t buf[BUF_SIZE];
|
| int rc;
|
| int (*func)();
|
|
|
| @@ -153,11 +182,41 @@
|
| assert(load_area[0] != buf[0]);
|
| }
|
|
|
| +/* Check code replacement constraints */
|
| +void test_illegal_code_replacment() {
|
| + uint8_t *load_area = allocate_code_space(1);
|
| + uint8_t buf[BUF_SIZE];
|
| + int rc;
|
| + int i;
|
| + int (*func)();
|
|
|
| + copy_and_pad_fragment(buf, sizeof(buf), &template_func, &template_func_end);
|
| + rc = nacl_dyncode_create(load_area, buf, sizeof(buf));
|
| + assert(rc == 0);
|
| + func = (int (*)()) (uintptr_t) load_area;
|
| + rc = func();
|
| + assert(rc == 1234);
|
| +
|
| + for (i = 0;
|
| + i < (sizeof(illegal_code_sections) / sizeof(struct code_section));
|
| + i++) {
|
| + printf("\t%s\n", illegal_code_sections[i].name);
|
| +
|
| + /* write illegal replacement to the same location */
|
| + copy_and_pad_fragment(buf, sizeof(buf), illegal_code_sections[i].start,
|
| + illegal_code_sections[i].end);
|
| + rc = nacl_dyncode_modify(load_area, buf, sizeof(buf));
|
| + assert(rc != 0);
|
| + func = (int (*)()) (uintptr_t) load_area;
|
| + rc = func();
|
| + assert(rc == 1234);
|
| + }
|
| +}
|
| +
|
| /* Check that we can't dynamically rewrite code. */
|
| void test_replacing_code_disabled() {
|
| uint8_t *load_area = allocate_code_space(1);
|
| - uint8_t buf[32];
|
| + uint8_t buf[BUF_SIZE];
|
| int rc;
|
| int (*func)();
|
|
|
| @@ -181,7 +240,7 @@
|
| /* Check that we can dynamically rewrite code. */
|
| void test_replacing_code_unaligned_disabled() {
|
| uint8_t *load_area = allocate_code_space(1);
|
| - uint8_t buf[32];
|
| + uint8_t buf[BUF_SIZE];
|
| int first_diff = 0;
|
| int rc;
|
| int (*func)();
|
| @@ -211,8 +270,7 @@
|
| /* Check that we can't delete code */
|
| void test_deleting_code_disabled() {
|
| uint8_t *load_area = allocate_code_space(1);
|
| - uint8_t buf[32];
|
| - int first_diff = 0;
|
| + uint8_t buf[BUF_SIZE];
|
| int rc;
|
| int (*func)();
|
|
|
| @@ -240,7 +298,7 @@
|
|
|
| #define RUN_TEST(test_func) (run_test(#test_func, test_func))
|
|
|
| -int main() {
|
| +int TestMain() {
|
| /* Turn off stdout buffering to aid debugging in case of a crash. */
|
| setvbuf(stdout, NULL, _IONBF, 0);
|
|
|
| @@ -249,6 +307,7 @@
|
| RUN_TEST(test_replacing_code);
|
| RUN_TEST(test_replacing_code_unaligned);
|
| RUN_TEST(test_deleting_code);
|
| + RUN_TEST(test_illegal_code_replacment);
|
| } else {
|
| printf("Code replacement DISABLED\n");
|
| RUN_TEST(test_replacing_code_disabled);
|
| @@ -259,3 +318,7 @@
|
| return 0;
|
| }
|
|
|
| +int main() {
|
| + return RunTests(TestMain);
|
| +}
|
| +
|
|
|