brintos

brintos / linux-shallow public Read only

0
0
Text · 6.6 KiB · 7597fc6 Raw
199 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (C) 2020 ARM Limited3 4#define _GNU_SOURCE5 6#include <errno.h>7#include <signal.h>8#include <stdio.h>9#include <stdlib.h>10#include <string.h>11#include <ucontext.h>12#include <sys/wait.h>13 14#include "kselftest.h"15#include "mte_common_util.h"16#include "mte_def.h"17 18#define BUFFER_SIZE		(5 * MT_GRANULE_SIZE)19#define RUNS			(MT_TAG_COUNT)20#define UNDERFLOW		MT_GRANULE_SIZE21#define OVERFLOW		MT_GRANULE_SIZE22 23static size_t page_size;24static int sizes[] = {25	1, 537, 989, 1269, MT_GRANULE_SIZE - 1, MT_GRANULE_SIZE,26	/* page size - 1*/ 0, /* page_size */ 0, /* page size + 1 */ 027};28 29static int check_child_tag_inheritance(char *ptr, int size, int mode)30{31	int i, parent_tag, child_tag, fault, child_status;32	pid_t child;33 34	parent_tag = MT_FETCH_TAG((uintptr_t)ptr);35	fault = 0;36 37	child = fork();38	if (child == -1) {39		ksft_print_msg("FAIL: child process creation\n");40		return KSFT_FAIL;41	} else if (child == 0) {42		mte_initialize_current_context(mode, (uintptr_t)ptr, size);43		/* Do copy on write */44		memset(ptr, '1', size);45		mte_wait_after_trig();46		if (cur_mte_cxt.fault_valid == true) {47			fault = 1;48			goto check_child_tag_inheritance_err;49		}50		for (i = 0 ; i < size ; i += MT_GRANULE_SIZE) {51			child_tag = MT_FETCH_TAG((uintptr_t)(mte_get_tag_address(ptr + i)));52			if (parent_tag != child_tag) {53				ksft_print_msg("FAIL: child mte tag mismatch\n");54				fault = 1;55				goto check_child_tag_inheritance_err;56			}57		}58		mte_initialize_current_context(mode, (uintptr_t)ptr, -UNDERFLOW);59		memset(ptr - UNDERFLOW, '2', UNDERFLOW);60		mte_wait_after_trig();61		if (cur_mte_cxt.fault_valid == false) {62			fault = 1;63			goto check_child_tag_inheritance_err;64		}65		mte_initialize_current_context(mode, (uintptr_t)ptr, size + OVERFLOW);66		memset(ptr + size, '3', OVERFLOW);67		mte_wait_after_trig();68		if (cur_mte_cxt.fault_valid == false) {69			fault = 1;70			goto check_child_tag_inheritance_err;71		}72check_child_tag_inheritance_err:73		_exit(fault);74	}75	/* Wait for child process to terminate */76	wait(&child_status);77	if (WIFEXITED(child_status))78		fault = WEXITSTATUS(child_status);79	else80		fault = 1;81	return (fault) ? KSFT_FAIL : KSFT_PASS;82}83 84static int check_child_memory_mapping(int mem_type, int mode, int mapping)85{86	char *ptr;87	int run, result;88	int item = ARRAY_SIZE(sizes);89 90	item = ARRAY_SIZE(sizes);91	mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);92	for (run = 0; run < item; run++) {93		ptr = (char *)mte_allocate_memory_tag_range(sizes[run], mem_type, mapping,94							    UNDERFLOW, OVERFLOW);95		if (check_allocated_memory_range(ptr, sizes[run], mem_type,96						 UNDERFLOW, OVERFLOW) != KSFT_PASS)97			return KSFT_FAIL;98		result = check_child_tag_inheritance(ptr, sizes[run], mode);99		mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW);100		if (result == KSFT_FAIL)101			return result;102	}103	return KSFT_PASS;104}105 106static int check_child_file_mapping(int mem_type, int mode, int mapping)107{108	char *ptr, *map_ptr;109	int run, fd, map_size, result = KSFT_PASS;110	int total = ARRAY_SIZE(sizes);111 112	mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);113	for (run = 0; run < total; run++) {114		fd = create_temp_file();115		if (fd == -1)116			return KSFT_FAIL;117 118		map_size = sizes[run] + OVERFLOW + UNDERFLOW;119		map_ptr = (char *)mte_allocate_file_memory(map_size, mem_type, mapping, false, fd);120		if (check_allocated_memory(map_ptr, map_size, mem_type, false) != KSFT_PASS) {121			close(fd);122			return KSFT_FAIL;123		}124		ptr = map_ptr + UNDERFLOW;125		mte_initialize_current_context(mode, (uintptr_t)ptr, sizes[run]);126		/* Only mte enabled memory will allow tag insertion */127		ptr = mte_insert_tags((void *)ptr, sizes[run]);128		if (!ptr || cur_mte_cxt.fault_valid == true) {129			ksft_print_msg("FAIL: Insert tags on file based memory\n");130			munmap((void *)map_ptr, map_size);131			close(fd);132			return KSFT_FAIL;133		}134		result = check_child_tag_inheritance(ptr, sizes[run], mode);135		mte_clear_tags((void *)ptr, sizes[run]);136		munmap((void *)map_ptr, map_size);137		close(fd);138		if (result != KSFT_PASS)139			return KSFT_FAIL;140	}141	return KSFT_PASS;142}143 144int main(int argc, char *argv[])145{146	int err;147	int item = ARRAY_SIZE(sizes);148 149	page_size = getpagesize();150	if (!page_size) {151		ksft_print_msg("ERR: Unable to get page size\n");152		return KSFT_FAIL;153	}154	sizes[item - 3] = page_size - 1;155	sizes[item - 2] = page_size;156	sizes[item - 1] = page_size + 1;157 158	err = mte_default_setup();159	if (err)160		return err;161 162	/* Register SIGSEGV handler */163	mte_register_signal(SIGSEGV, mte_default_handler);164	mte_register_signal(SIGBUS, mte_default_handler);165 166	/* Set test plan */167	ksft_set_plan(12);168 169	evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE),170		"Check child anonymous memory with private mapping, precise mode and mmap memory\n");171	evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED),172		"Check child anonymous memory with shared mapping, precise mode and mmap memory\n");173	evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE),174		"Check child anonymous memory with private mapping, imprecise mode and mmap memory\n");175	evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED),176		"Check child anonymous memory with shared mapping, imprecise mode and mmap memory\n");177	evaluate_test(check_child_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE),178		"Check child anonymous memory with private mapping, precise mode and mmap/mprotect memory\n");179	evaluate_test(check_child_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_SHARED),180		"Check child anonymous memory with shared mapping, precise mode and mmap/mprotect memory\n");181 182	evaluate_test(check_child_file_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE),183		"Check child file memory with private mapping, precise mode and mmap memory\n");184	evaluate_test(check_child_file_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED),185		"Check child file memory with shared mapping, precise mode and mmap memory\n");186	evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE),187		"Check child file memory with private mapping, imprecise mode and mmap memory\n");188	evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED),189		"Check child file memory with shared mapping, imprecise mode and mmap memory\n");190	evaluate_test(check_child_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE),191		"Check child file memory with private mapping, precise mode and mmap/mprotect memory\n");192	evaluate_test(check_child_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_SHARED),193		"Check child file memory with shared mapping, precise mode and mmap/mprotect memory\n");194 195	mte_restore_setup();196	ksft_print_cnts();197	return ksft_get_fail_cnt() == 0 ? KSFT_PASS : KSFT_FAIL;198}199