Skip to content

Commit

Permalink
Impelement 'samply setup' to codesign binary
Browse files Browse the repository at this point in the history
  • Loading branch information
vvuk committed May 20, 2024
1 parent 6cc0ae7 commit 949ae51
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 5 deletions.
66 changes: 66 additions & 0 deletions samply/src/mac/codesign_setup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use std::{env, io::Write};

const ENTITLEMENTS_XML: &str = r#"<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.debugger</key>
<true/>
</dict>
</plist>
"#;

pub fn codesign_setup() {
print!(
r#"
On macOS, attaching to an existing process is only allowed to binaries with
the com.apple.security.cs.debugger entitlement. The samply binary will be
signed with this entitlement for your local machine only. The following command
will be run:
codesign --force --options runtime --sign - \
--entitlements entitlements.xml {}
entitlements.xml contains:
{}
Press any key to continue, or Ctrl-C to cancel.
"#,
env::current_exe().unwrap().display(),
ENTITLEMENTS_XML
);

let mut input = String::new();
std::io::stdin()
.read_line(&mut input)
.expect("Failed to read input?");

let mut entitlements_file = tempfile::Builder::new()
.prefix("samply_entitlements")
.suffix(".xml")
.tempfile()
.expect("Failed to create temporary file for entitlements!");

entitlements_file
.write_all(ENTITLEMENTS_XML.as_bytes())
.expect("Failed to write entitlements to temporary file!");

let entitlements_path = entitlements_file.path();

// codesign for the current machine:
// codesign --force --options runtime --sign - --entitlements ent.xml target/debug/usamply
std::process::Command::new("codesign")
.arg("--force")
.arg("--options")
.arg("runtime")
.arg("--sign")
.arg("-")
.arg("--entitlements")
.arg(entitlements_path)
.arg(env::current_exe().unwrap())
.output()
.expect("Failed to run codesign!");

println!(r"Code signing successful!");
}
1 change: 1 addition & 0 deletions samply/src/mac/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#[allow(deref_nullptr)]
mod dyld_bindings;

pub mod codesign_setup;
mod error;
pub mod kernel_error;
mod mach_ipc;
Expand Down
8 changes: 6 additions & 2 deletions samply/src/mac/process_launcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,11 @@ impl ExistingProcessRunner {
return;
}

eprintln!("Error: task_for_pid for target task failed with error code {kr}. Does the profiler have entitlements?");
eprintln!("Error: task_for_pid for target task failed with error code {kr}.");
eprintln!(
"Please run 'samply setup' in order to grant appropriate entitlements"
);
eprintln!("to the binary.");
std::process::exit(1);
}
task_suspend(task);
Expand All @@ -301,7 +305,7 @@ impl ExistingProcessRunner {
};

// always root pid first
queue_pid(pid, true);
queue_pid(pid, false);

// TODO: find all its children

Expand Down
5 changes: 2 additions & 3 deletions samply/src/mac/profiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ pub fn start_recording(

let root_task_runner: Box<dyn RootTaskRunner> = match recording_mode {
RecordingMode::All => {
// TODO: Implement, by sudo launching a helper process which uses task_for_pid
eprintln!("Error: Profiling existing processes is currently not supported on macOS.");
eprintln!("You can only profile processes which you launch via samply.");
eprintln!("Error: Profiling all processes is not supported on macOS.");
eprintln!("You can only profile processes which you launch via samply, or attach to via --pid.");
std::process::exit(1)
}
RecordingMode::Pid(pid) => {
Expand Down
10 changes: 10 additions & 0 deletions samply/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ enum Action {
#[clap(hide = true)]
/// Used in the elevated helper process.
RunElevatedHelper(RunElevatedHelperArgs),

/// Codesign the samply binary on macOS to allow attaching to processes.
#[cfg(target_os = "macos")]
Setup,
}

#[derive(Debug, Args)]
Expand Down Expand Up @@ -333,13 +337,19 @@ fn main() {
};
std::process::exit(exit_status.code().unwrap_or(0));
}

#[cfg(target_os = "windows")]
Action::RunElevatedHelper(RunElevatedHelperArgs {
ipc_directory,
output_path,
}) => {
windows::run_elevated_helper(&ipc_directory, output_path);
}

#[cfg(target_os = "macos")]
Action::Setup => {
mac::codesign_setup::codesign_setup();
}
}
}

Expand Down

0 comments on commit 949ae51

Please sign in to comment.