Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lldb/include/lldb/lldb-enumerations.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ FLAGS_ENUM(LaunchFlags){
eLaunchFlagInheritTCCFromParent =
(1u << 12), ///< Don't make the inferior responsible for its own TCC
///< permissions but instead inherit them from its parent.
eLaunchFlagMemoryTagging =
(1u << 13), ///< Launch process with memory tagging explicitly enabled.
};

/// Thread Run Modes.
Expand Down
4 changes: 4 additions & 0 deletions lldb/source/Commands/CommandOptionsProcessLaunch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
break;
}

case 'M':
launch_info.GetFlags().Set(eLaunchFlagMemoryTagging);
break;

case 'c':
if (!option_arg.empty())
launch_info.SetShell(FileSpec(option_arg));
Expand Down
5 changes: 5 additions & 0 deletions lldb/source/Commands/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1173,6 +1173,11 @@ let Command = "process launch" in {
Arg<"Boolean">,
Desc<"Set whether to shell expand arguments to the process when "
"launching.">;
def process_launch_memory_tagging
: Option<"memory-tagging", "M">,
Desc<"Set whether to explicitly enable memory tagging when launching "
"the process. Requires hardware support. "
"(Only supported on Darwin.)">;
}

let Command = "process attach" in {
Expand Down
33 changes: 33 additions & 0 deletions lldb/source/Host/macosx/objcxx/Host.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1210,6 +1210,39 @@ static Status LaunchProcessPosixSpawn(const char *exe_path,
}
}

if (launch_info.GetFlags().Test(eLaunchFlagMemoryTagging)) {
// The following function configures the spawn attributes to launch the
// process with memory tagging explicitly enabled. We look it up
// dynamically since it is only available on newer OS. Does nothing on
// hardware which does not support MTE.
//
// int posix_spawnattr_set_use_sec_transition_shims_np(
// posix_spawnattr_t *attr, uint32_t flags);
//
Comment on lines +1213 to +1221
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine, but I still don't see the key line below.

Generally even in code I'm not familiar with, I could at least point to a boolean or API call that does the key work. Here these names don't suggest "memory tagging" to me.

Is the 0 value what turns on memory tagging? Is "sec_transition_shims_np" something like "when spawning do so with secure mode shims enabled, which causes the process to be memory tagged even though it wouldn't enable it itself"?

I'm just amazed there are so many words here and some of them mean memory tagging but I've no idea what :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The call of this API (through the function pointer) is the line that does the work.

posix_spawnattr_set_use_sec_transition_shims_np_fn(&attr, 0)

It means "launch with memory tagging enabled".

  • The naming of this function is unfortunate
  • We call through function pointer that is looked up via dlsym() because the function is not available on older OS
  • The flags=0 value allows for future, more specific semantics.
  • Everything else is just error handling

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment in the code along the lines of:
// This is the call that actually changes the setting.

Push this directly, no need for a PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in: c4d7c42

using posix_spawnattr_set_use_sec_transition_shims_np_t =
int (*)(posix_spawnattr_t *attr, uint32_t flags);
auto posix_spawnattr_set_use_sec_transition_shims_np_fn =
(posix_spawnattr_set_use_sec_transition_shims_np_t)dlsym(
RTLD_DEFAULT, "posix_spawnattr_set_use_sec_transition_shims_np");
if (posix_spawnattr_set_use_sec_transition_shims_np_fn) {
error =
Status(posix_spawnattr_set_use_sec_transition_shims_np_fn(&attr, 0),
eErrorTypePOSIX);
if (error.Fail()) {
LLDB_LOG(log,
"error: {0}, "
"posix_spawnattr_set_use_sec_transition_shims_np(&attr, 0)",
error);
return error;
}
} else {
LLDB_LOG(log,
"error: posix_spawnattr_set_use_sec_transition_shims_np not "
"available",
error);
}
}

// Don't set the binpref if a shell was provided. After all, that's only
// going to affect what version of the shell is launched, not what fork of
// the binary is launched. We insert "arch --arch <ARCH> as part of the
Expand Down
9 changes: 6 additions & 3 deletions lldb/test/API/macosx/mte/Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
C_SOURCES := main.c

EXE := uaf_mte
EXE := uaf

all: uaf_mte sign
binary-plain: uaf
binary-entitled: uaf sign

all: binary-entitled

include Makefile.rules

sign: mte-entitlements.plist uaf_mte
sign: mte-entitlements.plist uaf
ifeq ($(OS),Darwin)
codesign -s - -f --entitlements $^
endif
14 changes: 13 additions & 1 deletion lldb/test/API/macosx/mte/TestDarwinMTE.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,24 @@
from lldbsuite.test import lldbutil
import lldbsuite.test.cpu_feature as cpu_feature

exe_name = "uaf_mte" # Must match Makefile
exe_name = "uaf" # Must match Makefile


class TestDarwinMTE(TestBase):
NO_DEBUG_INFO_TESTCASE = True

@skipUnlessFeature(cpu_feature.AArch64.MTE)
def test_process_launch_memory_tagging(self):
self.build(make_targets=["binary-plain"])
self.createTestTarget(self.getBuildArtifact(exe_name))

self.expect("process launch", substrs=["exited with status = 0"])

self.expect(
"process launch --memory-tagging",
substrs=["stopped", "stop reason = EXC_ARM_MTE_TAG_FAULT"],
)

@skipUnlessFeature(cpu_feature.AArch64.MTE)
def test_tag_fault(self):
self.build()
Expand Down
Loading