-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JIRA: RTOS-666
- Loading branch information
Showing
6 changed files
with
290 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
DEFAULT_COMPONENTS = $(filter test_meterfs_%,$(ALL_COMPONENTS)) | ||
DEFAULT_COMPONENTS += $(SAMPLE_TESTS) | ||
DEFAULT_COMPONENTS += $(LIBC_UNIT_TESTS) | ||
DEFAULT_COMPONENTS += test-mprotect |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
test: | ||
targets: | ||
exclude: [armv7m7-imxrt106x-evk, armv7m7-imxrt117x-evk, armv7m4-stm32l4x6-nucleo] | ||
tests: | ||
- name: mprotect-fault | ||
harness: fault_harness.py | ||
execute: test-mprotect-fault | ||
|
||
- 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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/* | ||
* Phoenix-RTOS | ||
* | ||
* phoenix-rtos-test | ||
* | ||
* mprotect syscall tests | ||
* | ||
* Copyright 2023 Phoenix Systems | ||
* Author: Hubert Badocha | ||
* | ||
* This file is part of Phoenix-RTOS. | ||
* | ||
* %LICENSE% | ||
*/ | ||
|
||
#include <sys/mman.h> | ||
#include <pthread.h> | ||
#include <unistd.h> | ||
#include <errno.h> | ||
|
||
#include "unity_fixture.h" | ||
|
||
static long page_size; | ||
|
||
#define PAGES 4 | ||
|
||
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(0, page_size * PAGES, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | ||
TEST_ASSERT_NOT_NULL(area); | ||
|
||
for (int page = 0; page < PAGES; page++) { | ||
area[page * page_size] = 0x42; | ||
} | ||
|
||
TEST_ASSERT_EQUAL(0, mprotect(area, page_size * PAGES, PROT_READ)); | ||
Check warning on line 50 in mem/test_mprotect.c GitHub Actions / call-ci / build (armv7a7-imx6ull-evk)
Check warning on line 50 in mem/test_mprotect.c GitHub Actions / call-ci / build (armv7a9-zynq7000-zedboard)
Check warning on line 50 in mem/test_mprotect.c GitHub Actions / call-ci / build (armv7m7-imxrt105x-evk)
|
||
|
||
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)); | ||
} | ||
|
||
|
||
struct mprotect_data { | ||
pthread_cond_t cond; | ||
pthread_mutex_t mutex; | ||
enum { PROTECT, | ||
USE, | ||
EXIT } state; | ||
int prot; | ||
int res; | ||
unsigned char *area; | ||
size_t size; | ||
}; | ||
|
||
|
||
static void *mprotect_protect_thread(void *arg) | ||
{ | ||
struct mprotect_data *data = arg; | ||
|
||
TEST_ASSERT_EQUAL(0, pthread_mutex_lock(&data->mutex)); | ||
|
||
while (data->state != EXIT) { | ||
if (data->state == PROTECT) { | ||
data->res = mprotect(data->area, data->size, data->prot); | ||
data->state = USE; | ||
pthread_cond_signal(&data->cond); | ||
} | ||
TEST_ASSERT_EQUAL(0, pthread_cond_wait(&data->cond, &data->mutex)); | ||
} | ||
|
||
TEST_ASSERT_EQUAL(0, pthread_mutex_unlock(&data->mutex)); | ||
|
||
return NULL; | ||
} | ||
|
||
|
||
static int mprotect_in_thread(struct mprotect_data *data, int prot) | ||
{ | ||
data->prot = prot; | ||
data->state = PROTECT; | ||
|
||
TEST_ASSERT_EQUAL(0, pthread_cond_signal(&data->cond)); | ||
|
||
do { | ||
TEST_ASSERT_EQUAL(0, pthread_cond_wait(&data->cond, &data->mutex)); | ||
} while (data->state != USE); | ||
|
||
return data->res; | ||
} | ||
|
||
|
||
TEST(test_mprotect, test_mprotect_multicore) | ||
{ | ||
pthread_t thread; | ||
struct mprotect_data data = { | ||
.state = PROTECT, | ||
.size = page_size * PAGES, | ||
.prot = PROT_NONE, | ||
}; | ||
data.area = mmap(0, page_size * PAGES, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | ||
TEST_ASSERT_NOT_NULL(data.area); | ||
TEST_ASSERT_EQUAL(0, pthread_cond_init(&data.cond, NULL)); | ||
TEST_ASSERT_EQUAL(0, pthread_mutex_init(&data.mutex, NULL)); | ||
|
||
TEST_ASSERT_EQUAL(0, pthread_create(&thread, NULL, mprotect_protect_thread, &data)); | ||
|
||
TEST_ASSERT_EQUAL(0, pthread_mutex_lock(&data.mutex)); | ||
|
||
for (int page = 0; page < PAGES; page++) { | ||
data.area[page * page_size] = 0x42; | ||
} | ||
|
||
TEST_ASSERT_EQUAL(0, mprotect_in_thread(&data, PROT_READ)); | ||
|
||
for (int page = 0; page < PAGES; page++) { | ||
TEST_ASSERT_EQUAL(0x42, data.area[page * page_size]); | ||
} | ||
|
||
TEST_ASSERT_EQUAL(0, mprotect_in_thread(&data, PROT_READ | PROT_WRITE)); | ||
|
||
for (int page = 0; page < PAGES; page++) { | ||
data.area[(page * page_size) + 0x6] = 0x9; | ||
TEST_ASSERT_EQUAL(0x9, data.area[(page * page_size) + 0x6]); | ||
} | ||
|
||
data.state = EXIT; | ||
TEST_ASSERT_EQUAL(0, pthread_cond_signal(&data.cond)); | ||
TEST_ASSERT_EQUAL(0, pthread_mutex_unlock(&data.mutex)); | ||
|
||
|
||
TEST_ASSERT_EQUAL(0, pthread_join(thread, NULL)); | ||
|
||
TEST_ASSERT_EQUAL(0, munmap(data.area, data.size)); | ||
TEST_ASSERT_EQUAL(0, pthread_cond_destroy(&data.cond)); | ||
TEST_ASSERT_EQUAL(0, pthread_mutex_destroy(&data.mutex)); | ||
} | ||
|
||
|
||
TEST_GROUP_RUNNER(test_mprotect) | ||
{ | ||
RUN_TEST_CASE(test_mprotect, test_mprotect_singlecore); | ||
RUN_TEST_CASE(test_mprotect, test_mprotect_multicore); | ||
} | ||
|
||
|
||
static void runner(void) | ||
{ | ||
RUN_TEST_GROUP(test_mprotect); | ||
} | ||
|
||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
UnityMain(argc, (const char **)argv, runner); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <sys/mman.h> | ||
#include <pthread.h> | ||
#include <unistd.h> | ||
#include <errno.h> | ||
|
||
#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_NOT_NULL(area); | ||
|
||
TEST_ASSERT_EQUAL(0, mprotect(area, totalSize, PROT_READ)); | ||
Check warning on line 44 in mem/test_mprotect_fault.c GitHub Actions / call-ci / build (armv7a7-imx6ull-evk)
Check warning on line 44 in mem/test_mprotect_fault.c GitHub Actions / call-ci / build (armv7a9-zynq7000-zedboard)
Check warning on line 44 in mem/test_mprotect_fault.c GitHub Actions / call-ci / build (armv7m7-imxrt105x-evk)
|
||
|
||
area[0] = 0x42; /* Should generate fault. */ | ||
TEST_ASSERT_EQUAL(0x42, area[0]); /* Here to make sure compiler doesn't optimize away write. */ | ||
} | ||
|
||
|
||
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; | ||
} |