66#include < stdio.h>
77#include < stdint.h>
88#include < stdlib.h>
9+ #include < sys/mman.h>
910#include < sys/utsname.h>
1011#include < unistd.h>
1112
1415#include < string>
1516#include < unordered_map>
1617
18+ #include " ../../arm_mte.h"
19+
1720using namespace std ;
1821
1922using u8 = uint8_t ;
@@ -37,6 +40,10 @@ void *untag_pointer(void *ptr) {
3740 return (void *) ((uintptr_t ) ptr & mask);
3841}
3942
43+ void *set_pointer_tag (void *ptr, u8 tag) {
44+ return (void *) (((uintptr_t ) tag << 56 ) | (uintptr_t ) untag_pointer (ptr));
45+ }
46+
4047// This test checks that slab slot allocation uses tag that is distint from tags of its neighbors
4148// and from the tag of the previous allocation that used the same slot
4249void tag_distinctness () {
@@ -263,6 +270,39 @@ void untagged_write() {
263270 expect_write_segv (p[0 ] = 1 );
264271}
265272
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+
266306map<string, function<void ()>> tests = {
267307#define TEST (s ) { #s, s }
268308 TEST (tag_distinctness),
@@ -274,6 +314,7 @@ map<string, function<void()>> tests = {
274314 TEST (underflow_write),
275315 TEST (untagged_read),
276316 TEST (untagged_write),
317+ TEST (madvise_dontneed),
277318#undef TEST
278319};
279320
0 commit comments