diff --git a/Makefile.host b/Makefile.host index 347253c8..f92339cd 100644 --- a/Makefile.host +++ b/Makefile.host @@ -1,3 +1,4 @@ DEFAULT_COMPONENTS = $(filter test_meterfs_%,$(ALL_COMPONENTS)) DEFAULT_COMPONENTS += $(SAMPLE_TESTS) DEFAULT_COMPONENTS += $(LIBC_UNIT_TESTS) +DEFAULT_COMPONENTS += test-mprotect diff --git a/mem/Makefile b/mem/Makefile index 32c08178..eca36bef 100644 --- a/mem/Makefile +++ b/mem/Makefile @@ -1,10 +1,25 @@ # -# Makefile for libphoenix tests +# Makefile for mem tests # # Copyright 2019 Phoenix Systems # # %LICENSE% # +# LEGACY $(eval $(call add_test, test_mmap)) $(eval $(call add_test, test_malloc)) + +# UNITY + +NAME := test-mprotect +LOCAL_SRCS := test_mprotect.c +DEP_LIBS := unity + +include $(binary.mk) + +NAME := test-mprotect-fault +LOCAL_SRCS := test_mprotect_fault.c +DEP_LIBS := unity + +include $(binary.mk) diff --git a/mem/fault_harness.py b/mem/fault_harness.py new file mode 100644 index 00000000..8ab01c92 --- /dev/null +++ b/mem/fault_harness.py @@ -0,0 +1,9 @@ +from trunner.ctx import TestContext +from trunner.dut import Dut +from trunner.types import TestResult, Status + + +def harness(dut: Dut, ctx: TestContext, result: TestResult): + dut.expect("Exception", timeout=30) + + return TestResult(status=Status.OK) diff --git a/mem/test.yaml b/mem/test.yaml new file mode 100644 index 00000000..101a5baa --- /dev/null +++ b/mem/test.yaml @@ -0,0 +1,19 @@ +test: + tests: + - name: mprotect-fault + harness: fault_harness.py + execute: test-mprotect-fault + targets: + # mprotect: is noop on NOMMU architecture + exclude: [armv7m7-imxrt106x-evk, armv7m7-imxrt117x-evk, armv7m4-stm32l4x6-nucleo] + + - name: mprotect + type: unity + execute: test-mprotect + # FIXME: this reboot is placed here as after mprotect-fault is run target need to be rebooter. + # Currently rebooting after the test is not implemented in the runner. + reboot: True + targets: + # mprotect: is noop on NOMMU architecture + exclude: [armv7m7-imxrt106x-evk, armv7m7-imxrt117x-evk, armv7m4-stm32l4x6-nucleo] + diff --git a/mem/test_mprotect.c b/mem/test_mprotect.c new file mode 100644 index 00000000..7f4f1c3a --- /dev/null +++ b/mem/test_mprotect.c @@ -0,0 +1,86 @@ +/* + * Phoenix-RTOS + * + * phoenix-rtos-test + * + * mprotect syscall tests + * + * Copyright 2023 Phoenix Systems + * Author: Hubert Badocha + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#include +#include +#include +#include + +#include "unity_fixture.h" + + +#define PAGES 4 + + +static long page_size; + + +TEST_GROUP(test_mprotect); + + +TEST_SETUP(test_mprotect) +{ + page_size = sysconf(_SC_PAGESIZE); +} + + +TEST_TEAR_DOWN(test_mprotect) +{ +} + + +TEST(test_mprotect, test_mprotect_singlecore) +{ + unsigned char *area = mmap(NULL, page_size * PAGES, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + TEST_ASSERT(area != MAP_FAILED); + + for (int page = 0; page < PAGES; page++) { + area[page * page_size] = 0x42; + } + + TEST_ASSERT_EQUAL(0, mprotect(area, page_size * PAGES, PROT_READ)); + + for (int page = 0; page < PAGES; page++) { + TEST_ASSERT_EQUAL(0x42, area[page * page_size]); + } + + TEST_ASSERT_EQUAL(0, mprotect(area, page_size * PAGES, PROT_READ | PROT_WRITE)); + + for (int page = 0; page < PAGES; page++) { + area[(page * page_size) + 0x6] = 0x9; + TEST_ASSERT_EQUAL(0x9, area[(page * page_size) + 0x6]); + } + + TEST_ASSERT_EQUAL(0, munmap(area, page_size * PAGES)); +} + +TEST_GROUP_RUNNER(test_mprotect) +{ + RUN_TEST_CASE(test_mprotect, test_mprotect_singlecore); +} + + +static void runner(void) +{ + RUN_TEST_GROUP(test_mprotect); +} + + +int main(int argc, char *argv[]) +{ + UnityMain(argc, (const char **)argv, runner); + + return 0; +} diff --git a/mem/test_mprotect_fault.c b/mem/test_mprotect_fault.c new file mode 100644 index 00000000..343f1a4a --- /dev/null +++ b/mem/test_mprotect_fault.c @@ -0,0 +1,68 @@ +/* + * Phoenix-RTOS + * + * phoenix-rtos-test + * + * mprotect syscall tests + * + * Copyright 2023 Phoenix Systems + * Author: Hubert Badocha + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#include +#include +#include +#include + +#include "unity_fixture.h" + + +TEST_GROUP(test_mprotect_fault); + + +TEST_SETUP(test_mprotect_fault) +{ +} + + +TEST_TEAR_DOWN(test_mprotect_fault) +{ +} + + +TEST(test_mprotect_fault, unit) +{ + long pageSize = sysconf(_SC_PAGESIZE); + long totalSize = 4 * pageSize; + volatile unsigned char *area = mmap(NULL, totalSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS, -1, 0); + TEST_ASSERT(area != MAP_FAILED); + + TEST_ASSERT_EQUAL(0, mprotect((void *)area, totalSize, PROT_READ)); + + area[0] = 0x42; /* Should generate fault. */ + TEST_ASSERT_NOT_EQUAL(0x42, area[0]); +} + + +TEST_GROUP_RUNNER(test_mprotect_fault) +{ + RUN_TEST_CASE(test_mprotect_fault, unit); +} + + +static void runner(void) +{ + RUN_TEST_GROUP(test_mprotect_fault); +} + + +int main(int argc, char *argv[]) +{ + UnityMain(argc, (const char **)argv, runner); + + return 0; +}