brintos

brintos / linux-shallow public Read only

0
0
Text · 10.7 KiB · 17694ca Raw
266 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (C) 2020 ARM Limited3 4#define _GNU_SOURCE5 6#include <errno.h>7#include <fcntl.h>8#include <signal.h>9#include <stdio.h>10#include <stdlib.h>11#include <string.h>12#include <ucontext.h>13#include <sys/mman.h>14#include <sys/stat.h>15#include <sys/types.h>16 17#include "kselftest.h"18#include "mte_common_util.h"19#include "mte_def.h"20 21#define RUNS			(MT_TAG_COUNT)22#define UNDERFLOW		MT_GRANULE_SIZE23#define OVERFLOW		MT_GRANULE_SIZE24#define TAG_CHECK_ON		025#define TAG_CHECK_OFF		126 27static size_t page_size;28static int sizes[] = {29	1, 537, 989, 1269, MT_GRANULE_SIZE - 1, MT_GRANULE_SIZE,30	/* page size - 1*/ 0, /* page_size */ 0, /* page size + 1 */ 031};32 33static int check_mte_memory(char *ptr, int size, int mode, int tag_check)34{35	mte_initialize_current_context(mode, (uintptr_t)ptr, size);36	memset(ptr, '1', size);37	mte_wait_after_trig();38	if (cur_mte_cxt.fault_valid == true)39		return KSFT_FAIL;40 41	mte_initialize_current_context(mode, (uintptr_t)ptr, -UNDERFLOW);42	memset(ptr - UNDERFLOW, '2', UNDERFLOW);43	mte_wait_after_trig();44	if (cur_mte_cxt.fault_valid == false && tag_check == TAG_CHECK_ON)45		return KSFT_FAIL;46	if (cur_mte_cxt.fault_valid == true && tag_check == TAG_CHECK_OFF)47		return KSFT_FAIL;48 49	mte_initialize_current_context(mode, (uintptr_t)ptr, size + OVERFLOW);50	memset(ptr + size, '3', OVERFLOW);51	mte_wait_after_trig();52	if (cur_mte_cxt.fault_valid == false && tag_check == TAG_CHECK_ON)53		return KSFT_FAIL;54	if (cur_mte_cxt.fault_valid == true && tag_check == TAG_CHECK_OFF)55		return KSFT_FAIL;56 57	return KSFT_PASS;58}59 60static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, int tag_check)61{62	char *ptr, *map_ptr;63	int run, result, map_size;64	int item = ARRAY_SIZE(sizes);65 66	mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);67	for (run = 0; run < item; run++) {68		map_size = sizes[run] + OVERFLOW + UNDERFLOW;69		map_ptr = (char *)mte_allocate_memory(map_size, mem_type, mapping, false);70		if (check_allocated_memory(map_ptr, map_size, mem_type, false) != KSFT_PASS)71			return KSFT_FAIL;72 73		ptr = map_ptr + UNDERFLOW;74		mte_initialize_current_context(mode, (uintptr_t)ptr, sizes[run]);75		/* Only mte enabled memory will allow tag insertion */76		ptr = mte_insert_tags((void *)ptr, sizes[run]);77		if (!ptr || cur_mte_cxt.fault_valid == true) {78			ksft_print_msg("FAIL: Insert tags on anonymous mmap memory\n");79			munmap((void *)map_ptr, map_size);80			return KSFT_FAIL;81		}82		result = check_mte_memory(ptr, sizes[run], mode, tag_check);83		mte_clear_tags((void *)ptr, sizes[run]);84		mte_free_memory((void *)map_ptr, map_size, mem_type, false);85		if (result == KSFT_FAIL)86			return KSFT_FAIL;87	}88	return KSFT_PASS;89}90 91static int check_file_memory_mapping(int mem_type, int mode, int mapping, int tag_check)92{93	char *ptr, *map_ptr;94	int run, fd, map_size;95	int total = ARRAY_SIZE(sizes);96	int result = KSFT_PASS;97 98	mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);99	for (run = 0; run < total; run++) {100		fd = create_temp_file();101		if (fd == -1)102			return KSFT_FAIL;103 104		map_size = sizes[run] + UNDERFLOW + OVERFLOW;105		map_ptr = (char *)mte_allocate_file_memory(map_size, mem_type, mapping, false, fd);106		if (check_allocated_memory(map_ptr, map_size, mem_type, false) != KSFT_PASS) {107			close(fd);108			return KSFT_FAIL;109		}110		ptr = map_ptr + UNDERFLOW;111		mte_initialize_current_context(mode, (uintptr_t)ptr, sizes[run]);112		/* Only mte enabled memory will allow tag insertion */113		ptr = mte_insert_tags((void *)ptr, sizes[run]);114		if (!ptr || cur_mte_cxt.fault_valid == true) {115			ksft_print_msg("FAIL: Insert tags on file based memory\n");116			munmap((void *)map_ptr, map_size);117			close(fd);118			return KSFT_FAIL;119		}120		result = check_mte_memory(ptr, sizes[run], mode, tag_check);121		mte_clear_tags((void *)ptr, sizes[run]);122		munmap((void *)map_ptr, map_size);123		close(fd);124		if (result == KSFT_FAIL)125			break;126	}127	return result;128}129 130static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping)131{132	char *ptr, *map_ptr;133	int run, prot_flag, result, fd, map_size;134	int total = ARRAY_SIZE(sizes);135 136	prot_flag = PROT_READ | PROT_WRITE;137	mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);138	for (run = 0; run < total; run++) {139		map_size = sizes[run] + OVERFLOW + UNDERFLOW;140		ptr = (char *)mte_allocate_memory_tag_range(sizes[run], mem_type, mapping,141							    UNDERFLOW, OVERFLOW);142		if (check_allocated_memory_range(ptr, sizes[run], mem_type,143						 UNDERFLOW, OVERFLOW) != KSFT_PASS)144			return KSFT_FAIL;145		map_ptr = ptr - UNDERFLOW;146		/* Try to clear PROT_MTE property and verify it by tag checking */147		if (mprotect(map_ptr, map_size, prot_flag)) {148			mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type,149						  UNDERFLOW, OVERFLOW);150			ksft_print_msg("FAIL: mprotect not ignoring clear PROT_MTE property\n");151			return KSFT_FAIL;152		}153		result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON);154		mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW);155		if (result != KSFT_PASS)156			return KSFT_FAIL;157 158		fd = create_temp_file();159		if (fd == -1)160			return KSFT_FAIL;161		ptr = (char *)mte_allocate_file_memory_tag_range(sizes[run], mem_type, mapping,162								 UNDERFLOW, OVERFLOW, fd);163		if (check_allocated_memory_range(ptr, sizes[run], mem_type,164						 UNDERFLOW, OVERFLOW) != KSFT_PASS) {165			close(fd);166			return KSFT_FAIL;167		}168		map_ptr = ptr - UNDERFLOW;169		/* Try to clear PROT_MTE property and verify it by tag checking */170		if (mprotect(map_ptr, map_size, prot_flag)) {171			ksft_print_msg("FAIL: mprotect not ignoring clear PROT_MTE property\n");172			mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type,173						  UNDERFLOW, OVERFLOW);174			close(fd);175			return KSFT_FAIL;176		}177		result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON);178		mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW);179		close(fd);180		if (result != KSFT_PASS)181			return KSFT_FAIL;182	}183	return KSFT_PASS;184}185 186int main(int argc, char *argv[])187{188	int err;189	int item = ARRAY_SIZE(sizes);190 191	err = mte_default_setup();192	if (err)193		return err;194	page_size = getpagesize();195	if (!page_size) {196		ksft_print_msg("ERR: Unable to get page size\n");197		return KSFT_FAIL;198	}199	sizes[item - 3] = page_size - 1;200	sizes[item - 2] = page_size;201	sizes[item - 1] = page_size + 1;202 203	/* Register signal handlers */204	mte_register_signal(SIGBUS, mte_default_handler);205	mte_register_signal(SIGSEGV, mte_default_handler);206 207	/* Set test plan */208	ksft_set_plan(22);209 210	mte_enable_pstate_tco();211 212	evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_OFF),213	"Check anonymous memory with private mapping, sync error mode, mmap memory and tag check off\n");214	evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_OFF),215	"Check file memory with private mapping, sync error mode, mmap/mprotect memory and tag check off\n");216 217	mte_disable_pstate_tco();218	evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_NONE_ERR, MAP_PRIVATE, TAG_CHECK_OFF),219	"Check anonymous memory with private mapping, no error mode, mmap memory and tag check off\n");220	evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_NONE_ERR, MAP_PRIVATE, TAG_CHECK_OFF),221	"Check file memory with private mapping, no error mode, mmap/mprotect memory and tag check off\n");222 223	evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),224	"Check anonymous memory with private mapping, sync error mode, mmap memory and tag check on\n");225	evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),226	"Check anonymous memory with private mapping, sync error mode, mmap/mprotect memory and tag check on\n");227	evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON),228	"Check anonymous memory with shared mapping, sync error mode, mmap memory and tag check on\n");229	evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON),230	"Check anonymous memory with shared mapping, sync error mode, mmap/mprotect memory and tag check on\n");231	evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),232	"Check anonymous memory with private mapping, async error mode, mmap memory and tag check on\n");233	evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),234	"Check anonymous memory with private mapping, async error mode, mmap/mprotect memory and tag check on\n");235	evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON),236	"Check anonymous memory with shared mapping, async error mode, mmap memory and tag check on\n");237	evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON),238	"Check anonymous memory with shared mapping, async error mode, mmap/mprotect memory and tag check on\n");239 240	evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),241	"Check file memory with private mapping, sync error mode, mmap memory and tag check on\n");242	evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),243	"Check file memory with private mapping, sync error mode, mmap/mprotect memory and tag check on\n");244	evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON),245	"Check file memory with shared mapping, sync error mode, mmap memory and tag check on\n");246	evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON),247	"Check file memory with shared mapping, sync error mode, mmap/mprotect memory and tag check on\n");248	evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),249	"Check file memory with private mapping, async error mode, mmap memory and tag check on\n");250	evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON),251	"Check file memory with private mapping, async error mode, mmap/mprotect memory and tag check on\n");252	evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON),253	"Check file memory with shared mapping, async error mode, mmap memory and tag check on\n");254	evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON),255	"Check file memory with shared mapping, async error mode, mmap/mprotect memory and tag check on\n");256 257	evaluate_test(check_clear_prot_mte_flag(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE),258	"Check clear PROT_MTE flags with private mapping, sync error mode and mmap memory\n");259	evaluate_test(check_clear_prot_mte_flag(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE),260	"Check clear PROT_MTE flags with private mapping and sync error mode and mmap/mprotect memory\n");261 262	mte_restore_setup();263	ksft_print_cnts();264	return ksft_get_fail_cnt() == 0 ? KSFT_PASS : KSFT_FAIL;265}266