~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/arm64/mte/check_child_memory.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 // Copyright (C) 2020 ARM Limited
  3 
  4 #define _GNU_SOURCE
  5 
  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_SIZE
 21 #define OVERFLOW                MT_GRANULE_SIZE
 22 
 23 static size_t page_size;
 24 static 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 */ 0
 27 };
 28 
 29 static 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                 }
 72 check_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         else
 80                 fault = 1;
 81         return (fault) ? KSFT_FAIL : KSFT_PASS;
 82 }
 83 
 84 static 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 
106 static 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 
144 int 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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php