mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-03 16:41:26 +01:00
fix(cli,core): keep secret-holding commands out of core dumps
Only `pdfs daemon` marked itself non-dumpable, though `mount`, `login`, `unlock` and `logout` hold the same passphrases or tokens. All five now do. The file-manager script also passes each path after `--`, so a file named like an option stays a path (B240).
This commit is contained in:
1 parent
4836c5a84a
commit
6456f503f1
3 files changed
+73
-4
No files matched your search
@@ -831,6 +831,20 @@ fn main() -> Result<()> {
|
||||
|
||||
let cli = Cli::parse();
|
||||
JSON_OUTPUT.store(cli.json, std::sync::atomic::Ordering::Relaxed);
|
||||
// The commands that hold the password, the key passphrases or the session
|
||||
// tokens in memory: keep them out of core dumps and away from same-user
|
||||
// ptrace. Only the daemon did, though `mount` holds the same keys for as
|
||||
// long as it runs.
|
||||
if matches!(
|
||||
cli.command,
|
||||
Command::Login { .. }
|
||||
| Command::Unlock { .. }
|
||||
| Command::Logout
|
||||
| Command::Mount { .. }
|
||||
| Command::Daemon { .. }
|
||||
) {
|
||||
pdfs_core::kernelkey::forbid_dumps();
|
||||
}
|
||||
match cli.command {
|
||||
Command::Login { username, remember } => cmd_login(username, remember),
|
||||
Command::Unlock { remember } => cmd_unlock(remember),
|
||||
@@ -2227,9 +2241,6 @@ where
|
||||
/// an external unmount triggers a remount; errors back off and retry. This is
|
||||
/// the entry point for the systemd user service.
|
||||
fn cmd_daemon(mountpoint: Option<PathBuf>) -> Result<()> {
|
||||
// The daemon holds the account's key passphrases in memory; keep them out
|
||||
// of core dumps and away from same-user ptrace.
|
||||
pdfs_core::kernelkey::forbid_dumps();
|
||||
loop {
|
||||
// Wait until a session is stored. The GUI enables this service on login,
|
||||
// but the service may also start at boot before the user has logged in.
|
||||
@@ -3787,6 +3798,18 @@ mod login_wait_tests {
|
||||
assert_eq!(login_poll_delay(u32::MAX), Duration::from_secs(15));
|
||||
}
|
||||
|
||||
/// The file-manager script passes each selected path after `--`, so a
|
||||
/// file named like an option is still the path.
|
||||
#[test]
|
||||
fn a_path_after_a_double_dash_is_a_path_even_when_it_looks_like_a_flag() {
|
||||
let cli = Cli::try_parse_from(["pdfs", "pin", "--", "--json"]).unwrap();
|
||||
assert!(!cli.json);
|
||||
match cli.command {
|
||||
Command::Pin { path } => assert_eq!(path, PathBuf::from("--json")),
|
||||
_ => panic!("not a pin"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_waited_for_run_that_did_not_fully_succeed_exits_with_an_error() {
|
||||
assert!(finished_run("the import", Some((0, false, None))).is_ok());
|
||||
|
||||
@@ -23,6 +23,11 @@ const SCRIPTS: [(&str, &str); 2] = [
|
||||
/// `NAUTILUS_SCRIPT_SELECTED_FILE_PATHS`; the positional args carry the same
|
||||
/// selection when the script runs on a local (non-URI) folder, so we prefer the
|
||||
/// environment and fall back to `"$@"` for the Nemo/Caja variants.
|
||||
///
|
||||
/// The `--` keeps a file named like an option, such as `--json`, a path. A
|
||||
/// name with a newline in it still arrives split in two from Nautilus, whose
|
||||
/// list is newline-separated; `pdfs` then fails on both halves, which touches
|
||||
/// nothing.
|
||||
fn script_body(subcommand: &str) -> String {
|
||||
format!(
|
||||
"#!/bin/sh\n\
|
||||
@@ -41,7 +46,7 @@ fn script_body(subcommand: &str) -> String {
|
||||
\n\
|
||||
printf '%s' \"$paths\" | while IFS= read -r path; do\n\
|
||||
\x20 [ -n \"$path\" ] || continue\n\
|
||||
\x20 pdfs {subcommand} \"$path\" || exit 1\n\
|
||||
\x20 pdfs {subcommand} -- \"$path\" || exit 1\n\
|
||||
done\n"
|
||||
)
|
||||
}
|
||||
@@ -95,3 +100,13 @@ fn write_scripts(dir: &PathBuf) -> io::Result<()> {
|
||||
tracing::debug!("installed file-manager scripts in {dir:?}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::script_body;
|
||||
|
||||
#[test]
|
||||
fn the_script_ends_options_before_each_path() {
|
||||
assert!(script_body("pin").contains(r#"pdfs pin -- "$path""#));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user