123 lines · python
1"""Test MTE Memory Tagging on Apple platforms"""2 3import lldb4import re5from lldbsuite.test.decorators import *6from lldbsuite.test.lldbtest import *7from lldbsuite.test import lldbutil8import lldbsuite.test.cpu_feature as cpu_feature9 10exe_name = "uaf" # Must match Makefile11 12 13class TestDarwinMTE(TestBase):14 NO_DEBUG_INFO_TESTCASE = True15 16 @skipUnlessFeature(cpu_feature.AArch64.MTE)17 def test_process_launch_memory_tagging(self):18 self.build(make_targets=["binary-plain"])19 self.createTestTarget(self.getBuildArtifact(exe_name))20 21 self.expect("process launch", substrs=["exited with status = 0"])22 23 self.expect(24 "process launch --memory-tagging",25 substrs=["stopped", "stop reason = EXC_ARM_MTE_TAG_FAULT"],26 )27 28 @skipUnlessFeature(cpu_feature.AArch64.MTE)29 def test_tag_fault(self):30 self.build()31 exe = self.getBuildArtifact(exe_name)32 33 target = self.dbg.CreateTarget(exe)34 self.assertTrue(target, VALID_TARGET)35 36 process = target.LaunchSimple(None, None, None)37 self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)38 39 self.expect(40 "thread info",41 substrs=[42 "stop reason = EXC_ARM_MTE_TAG_FAULT",43 "MTE tag mismatch detected",44 ],45 )46 47 @skipUnlessFeature(cpu_feature.AArch64.MTE)48 def test_memory_region(self):49 self.build()50 lldbutil.run_to_source_breakpoint(51 self, "// before free", lldb.SBFileSpec("main.c"), exe_name=exe_name52 )53 54 # (lldb) memory region ptr55 # [0x00000001005ec000-0x00000001009ec000) rw-56 # memory tagging: enabled57 # Modified memory (dirty) page list provided, 2 entries.58 # Dirty pages: 0x1005ec000, 0x1005fc000.59 self.expect("memory region ptr", substrs=["memory tagging: enabled"])60 61 @skipUnlessFeature(cpu_feature.AArch64.MTE)62 def test_memory_read_show_tags(self):63 self.build()64 lldbutil.run_to_source_breakpoint(65 self, "// before free", lldb.SBFileSpec("main.c"), exe_name=exe_name66 )67 68 # (lldb) memory read ptr-16 ptr+48 --show-tags69 # 0x7d2c00930: 00 00 00 00 00 00 00 00 d0 e3 a5 0a 02 00 00 00 ................ (tag: 0x3)70 # 0x7d2c00940: 48 65 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00 Hello........... (tag: 0xb)71 # 0x7d2c00950: 57 6f 72 6c 64 00 00 00 00 00 00 00 00 00 00 00 World........... (tag: 0xb)72 # 0x7d2c00960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ (tag: 0x9)73 self.expect(74 "memory read ptr-16 ptr+48 --show-tags",75 substrs=[" Hello...........", " World..........."],76 patterns=[r"(.*\(tag: 0x[0-9a-f]\)\n){4}"],77 )78 79 def _parse_pointer_tag(self, output):80 return re.search(r"Logical tag: (0x[0-9a-f])", output).group(1)81 82 def _parse_memory_tags(self, output, expected_tag_count):83 tags = re.findall(r"\): (0x[0-9a-f])", output)84 self.assertEqual(len(tags), expected_tag_count)85 return tags86 87 @skipUnlessFeature(cpu_feature.AArch64.MTE)88 def test_memory_tag_read(self):89 self.build()90 lldbutil.run_to_source_breakpoint(91 self, "// before free", lldb.SBFileSpec("main.c"), exe_name=exe_name92 )93 94 # (lldb) memory tag read ptr-1 ptr+3395 # Logical tag: 0x596 # Allocation tags:97 # [0x100a65a40, 0x100a65a50): 0xf (mismatch)98 # [0x100a65a50, 0x100a65a60): 0x599 # [0x100a65a60, 0x100a65a70): 0x5100 # [0x100a65a70, 0x100a65a80): 0x2 (mismatch)101 self.expect(102 "memory tag read ptr-1 ptr+33",103 substrs=["Logical tag: 0x", "Allocation tags:", "(mismatch)"],104 patterns=[r"(\[.*\): 0x[0-9a-f].*\n){4}"],105 )106 output = self.res.GetOutput()107 self.assertEqual(output.count("(mismatch)"), 2)108 ptr_tag = self._parse_pointer_tag(output)109 tags = self._parse_memory_tags(output, 4)110 self.assertEqual(tags[1], ptr_tag)111 self.assertEqual(tags[2], ptr_tag)112 self.assertNotEqual(tags[0], ptr_tag) # Memory that comes before/after113 self.assertNotEqual(tags[3], ptr_tag) # allocation has different tag.114 115 # Continue running until MTE fault116 self.expect("process continue", substrs=["stop reason = EXC_ARM_MTE_TAG_FAULT"])117 118 self.runCmd("memory tag read ptr-1 ptr+33")119 output = self.res.GetOutput()120 self.assertEqual(output.count("(mismatch)"), 4)121 tags = self._parse_memory_tags(output, 4)122 self.assertTrue(all(t != ptr_tag for t in tags))123