6
6
#include < stdio.h>
7
7
#include < stdint.h>
8
8
#include < stdlib.h>
9
+ #include < sys/mman.h>
9
10
#include < sys/utsname.h>
10
11
#include < unistd.h>
11
12
14
15
#include < string>
15
16
#include < unordered_map>
16
17
18
+ #include " ../../arm_mte.h"
19
+
17
20
using namespace std ;
18
21
19
22
using u8 = uint8_t ;
@@ -37,6 +40,10 @@ void *untag_pointer(void *ptr) {
37
40
return (void *) ((uintptr_t ) ptr & mask);
38
41
}
39
42
43
+ void *set_pointer_tag (void *ptr, u8 tag) {
44
+ return (void *) (((uintptr_t ) tag << 56 ) | (uintptr_t ) untag_pointer (ptr));
45
+ }
46
+
40
47
// This test checks that slab slot allocation uses tag that is distint from tags of its neighbors
41
48
// and from the tag of the previous allocation that used the same slot
42
49
void tag_distinctness () {
@@ -263,6 +270,39 @@ void untagged_write() {
263
270
expect_write_segv (p[0 ] = 1 );
264
271
}
265
272
273
+ // checks that each of memory locations inside the buffer is tagged with expected_tag
274
+ void check_tag (void *buf, size_t len, u8 expected_tag) {
275
+ for (size_t i = 0 ; i < len; ++i) {
276
+ assert (get_pointer_tag (__arm_mte_get_tag ((void *) ((uintptr_t ) buf + i))) == expected_tag);
277
+ }
278
+ }
279
+
280
+ void madvise_dontneed () {
281
+ const size_t len = 100'000 ;
282
+ void *ptr = mmap (NULL , len, PROT_READ | PROT_WRITE | PROT_MTE, MAP_ANONYMOUS | MAP_PRIVATE, -1 , 0 );
283
+ assert (ptr != MAP_FAILED);
284
+
285
+ // check that 0 is the initial tag
286
+ check_tag (ptr, len, 0 );
287
+
288
+ arm_mte_tag_and_clear_mem (set_pointer_tag (ptr, 1 ), len);
289
+ check_tag (ptr, len, 1 );
290
+
291
+ memset (set_pointer_tag (ptr, 1 ), 1 , len);
292
+
293
+ assert (madvise (ptr, len, MADV_DONTNEED) == 0 );
294
+ // check that MADV_DONTNEED resets the tag
295
+ check_tag (ptr, len, 0 );
296
+
297
+ // check that MADV_DONTNEED clears the memory
298
+ for (size_t i = 0 ; i < len; ++i) {
299
+ assert (((u8 *) ptr)[i] == 0 );
300
+ }
301
+
302
+ // check that mistagged read after MADV_DONTNEED fails
303
+ expect_read_segv (*((u8 *) set_pointer_tag (ptr, 1 )));
304
+ }
305
+
266
306
map<string, function<void ()>> tests = {
267
307
#define TEST (s ) { #s, s }
268
308
TEST (tag_distinctness),
@@ -274,6 +314,7 @@ map<string, function<void()>> tests = {
274
314
TEST (underflow_write),
275
315
TEST (untagged_read),
276
316
TEST (untagged_write),
317
+ TEST (madvise_dontneed),
277
318
#undef TEST
278
319
};
279
320
0 commit comments