Skip to content

Commit 5bcb5ba

Browse files
JDevlieghereyln
authored andcommitted
[lldb] Add process launch --memory-tagging option
For debugging and bug-finding workflows, support launching processes with MTE for binaries that are not MTE entitled.
1 parent b92483c commit 5bcb5ba

File tree

8 files changed

+62
-5
lines changed

8 files changed

+62
-5
lines changed

lldb/include/lldb/lldb-enumerations.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ FLAGS_ENUM(LaunchFlags){
130130
eLaunchFlagInheritTCCFromParent =
131131
(1u << 12), ///< Don't make the inferior responsible for its own TCC
132132
///< permissions but instead inherit them from its parent.
133+
eLaunchFlagMemoryTagging =
134+
(1u << 13), ///< Launch with memory tagging (MTE).
133135
};
134136

135137
/// Thread Run Modes.

lldb/source/Commands/CommandObjectProcess.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,9 @@ class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach {
181181
disable_aslr = target->GetDisableASLR();
182182
}
183183

184+
if (m_options.memory_tagging == eLazyBoolYes)
185+
m_options.launch_info.GetFlags().Set(eLaunchFlagMemoryTagging);
186+
184187
if (!m_class_options.GetName().empty()) {
185188
m_options.launch_info.SetProcessPluginName("ScriptedProcess");
186189
ScriptedMetadataSP metadata_sp = std::make_shared<ScriptedMetadata>(

lldb/source/Commands/CommandOptionsProcessLaunch.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
127127
break;
128128
}
129129

130+
case 'M':
131+
memory_tagging = true;
132+
break;
133+
130134
case 'c':
131135
if (!option_arg.empty())
132136
launch_info.SetShell(FileSpec(option_arg));

lldb/source/Commands/CommandOptionsProcessLaunch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class CommandOptionsProcessLaunch : public lldb_private::OptionGroup {
3434
lldb_private::ExecutionContext *execution_context) override {
3535
launch_info.Clear();
3636
disable_aslr = lldb_private::eLazyBoolCalculate;
37+
memory_tagging = false;
3738
}
3839

3940
llvm::ArrayRef<lldb_private::OptionDefinition> GetDefinitions() override;
@@ -42,6 +43,7 @@ class CommandOptionsProcessLaunch : public lldb_private::OptionGroup {
4243

4344
lldb_private::ProcessLaunchInfo launch_info;
4445
lldb_private::LazyBool disable_aslr;
46+
bool memory_tagging;
4547
}; // CommandOptionsProcessLaunch
4648

4749
} // namespace lldb_private

lldb/source/Commands/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,10 @@ let Command = "process launch" in {
11731173
Arg<"Boolean">,
11741174
Desc<"Set whether to shell expand arguments to the process when "
11751175
"launching.">;
1176+
def process_launch_memory_tagging
1177+
: Option<"memory-tagging", "M">,
1178+
Desc<"Set whether to enable memory tagging (MTE) when launching the "
1179+
"process.">;
11761180
}
11771181

11781182
let Command = "process attach" in {

lldb/source/Host/macosx/objcxx/Host.mm

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,33 @@ static Status LaunchProcessPosixSpawn(const char *exe_path,
12101210
}
12111211
}
12121212

1213+
if (launch_info.GetFlags().Test(eLaunchFlagMemoryTagging)) {
1214+
typedef int (*posix_spawnattr_set_use_sec_transition_shims_np_t)(
1215+
posix_spawnattr_t *attr, uint32_t flags);
1216+
posix_spawnattr_set_use_sec_transition_shims_np_t
1217+
posix_spawnattr_set_use_sec_transition_shims_np_fn =
1218+
(posix_spawnattr_set_use_sec_transition_shims_np_t)dlsym(
1219+
RTLD_DEFAULT,
1220+
"posix_spawnattr_set_use_sec_transition_shims_np");
1221+
if (posix_spawnattr_set_use_sec_transition_shims_np_fn) {
1222+
error =
1223+
Status(posix_spawnattr_set_use_sec_transition_shims_np_fn(&attr, 0),
1224+
eErrorTypePOSIX);
1225+
if (error.Fail()) {
1226+
LLDB_LOG(log,
1227+
"error: {0}, "
1228+
"posix_spawnattr_set_use_sec_transition_shims_np(&attr, 0)",
1229+
error);
1230+
return error;
1231+
}
1232+
} else {
1233+
LLDB_LOG(log,
1234+
"error: posix_spawnattr_set_use_sec_transition_shims_np not "
1235+
"available",
1236+
error);
1237+
}
1238+
}
1239+
12131240
// Don't set the binpref if a shell was provided. After all, that's only
12141241
// going to affect what version of the shell is launched, not what fork of
12151242
// the binary is launched. We insert "arch --arch <ARCH> as part of the

lldb/test/API/macosx/mte/Makefile

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
C_SOURCES := main.c
22

3-
EXE := uaf_mte
3+
EXE := uaf
44

5-
all: uaf_mte sign
5+
binary-plain: uaf
6+
binary-entitled: uaf sign
7+
8+
all: binary-entitled
69

710
include Makefile.rules
811

9-
sign: mte-entitlements.plist uaf_mte
12+
sign: mte-entitlements.plist uaf
1013
ifeq ($(OS),Darwin)
1114
codesign -s - -f --entitlements $^
1215
endif

lldb/test/API/macosx/mte/TestDarwinMTE.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,24 @@
77
from lldbsuite.test import lldbutil
88
import lldbsuite.test.cpu_feature as cpu_feature
99

10-
exe_name = "uaf_mte" # Must match Makefile
10+
exe_name = "uaf" # Must match Makefile
1111

1212

1313
class TestDarwinMTE(TestBase):
1414
NO_DEBUG_INFO_TESTCASE = True
1515

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+
1628
@skipUnlessFeature(cpu_feature.AArch64.MTE)
1729
def test_tag_fault(self):
1830
self.build()
@@ -47,7 +59,7 @@ def test_memory_region(self):
4759
self.expect("memory region ptr", substrs=["memory tagging: enabled"])
4860

4961
@skipUnlessFeature(cpu_feature.AArch64.MTE)
50-
def test_memory_read_with_tags(self):
62+
def test_memory_read_show_tags(self):
5163
self.build()
5264
lldbutil.run_to_source_breakpoint(
5365
self, "// before free", lldb.SBFileSpec("main.c"), exe_name=exe_name

0 commit comments

Comments
 (0)