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

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

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ 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 <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_SIZE
 23 #define OVERFLOW                MT_GRANULE_SIZE
 24 #define TAG_CHECK_ON            0
 25 #define TAG_CHECK_OFF           1
 26 
 27 static size_t page_size;
 28 static 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 */ 0
 31 };
 32 
 33 static 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 
 60 static 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 
 91 static 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 
130 static 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 
186 int 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 

~ [ 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