Skip to content

Commit

Permalink
mem: add mprotect tests
Browse files Browse the repository at this point in the history
JIRA: RTOS-666
  • Loading branch information
badochov committed Nov 14, 2023
1 parent 36b0b78 commit c53ba48
Show file tree
Hide file tree
Showing 6 changed files with 290 additions and 1 deletion.
1 change: 1 addition & 0 deletions Makefile.host
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
17 changes: 16 additions & 1 deletion mem/Makefile
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)
9 changes: 9 additions & 0 deletions mem/fault_harness.py
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)
15 changes: 15 additions & 0 deletions mem/test.yaml
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

181 changes: 181 additions & 0 deletions mem/test_mprotect.c
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

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7a7-imx6ull-evk)

implicit declaration of function 'mprotect' [-Wimplicit-function-declaration]

Check warning on line 50 in mem/test_mprotect.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7a9-zynq7000-zedboard)

implicit declaration of function 'mprotect' [-Wimplicit-function-declaration]

Check warning on line 50 in mem/test_mprotect.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7m7-imxrt105x-evk)

implicit declaration of function 'mprotect' [-Wimplicit-function-declaration]

Check warning on line 50 in mem/test_mprotect.c

View workflow job for this annotation

GitHub Actions / call-ci / build (ia32-generic-pc)

implicit declaration of function 'mprotect' [-Wimplicit-function-declaration]

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;
}
68 changes: 68 additions & 0 deletions mem/test_mprotect_fault.c
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

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7a7-imx6ull-evk)

implicit declaration of function 'mprotect' [-Wimplicit-function-declaration]

Check warning on line 44 in mem/test_mprotect_fault.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7a9-zynq7000-zedboard)

implicit declaration of function 'mprotect' [-Wimplicit-function-declaration]

Check warning on line 44 in mem/test_mprotect_fault.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7m7-imxrt105x-evk)

implicit declaration of function 'mprotect' [-Wimplicit-function-declaration]

Check warning on line 44 in mem/test_mprotect_fault.c

View workflow job for this annotation

GitHub Actions / call-ci / build (ia32-generic-pc)

implicit declaration of function 'mprotect' [-Wimplicit-function-declaration]

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;
}

0 comments on commit c53ba48

Please sign in to comment.