From 81ce4264dff09b00067e71eb9af0022118595558 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 7 Mar 2025 14:47:34 -0400 Subject: [PATCH] compute: add response to OUTPUT This allows rejecting output filenames that are outside the repository, and also handles converting eg "-foo" to "./-foo" to prevent a command that it's passed to interpreting the output filename as a dashed option. --- Remote/Compute.hs | 4 ++++ Utility/SafeCommand.hs | 1 + .../compute_special_remote_interface.mdwn | 19 ++++++++++++------- .../compute/git-annex-compute-imageconvert | 7 ++----- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/Remote/Compute.hs b/Remote/Compute.hs index b6ec907bda..d4bcd3359a 100644 --- a/Remote/Compute.hs +++ b/Remote/Compute.hs @@ -472,6 +472,10 @@ runComputeProgram (ComputeProgram program) state (ImmutableState immutablestate) Just (ProcessOutput f) -> do let f' = toOsPath f checksafefile tmpdir subdir f' "output" + -- Modify filename so eg "-foo" becomes "./-foo" + liftIO $ hPutStrLn (stdinHandle p) $ + toCommand' (File f) + liftIO $ hFlush (stdinHandle p) knownoutput <- case M.lookup f' (computeOutputs $ computeState result) of Nothing -> return False Just mk -> do diff --git a/Utility/SafeCommand.hs b/Utility/SafeCommand.hs index 6f9419cd8c..aa96bda0ea 100644 --- a/Utility/SafeCommand.hs +++ b/Utility/SafeCommand.hs @@ -10,6 +10,7 @@ module Utility.SafeCommand ( CommandParam(..), toCommand, + toCommand', boolSystem, boolSystem', boolSystemEnv, diff --git a/doc/design/compute_special_remote_interface.mdwn b/doc/design/compute_special_remote_interface.mdwn index 2c97946a81..5a55e2fe2c 100644 --- a/doc/design/compute_special_remote_interface.mdwn +++ b/doc/design/compute_special_remote_interface.mdwn @@ -16,15 +16,15 @@ Whatever values the user passes to `git-annex addcomputed` are passed to the program in `ARGV`, followed by any values that the user provided to `git-annex initremote`. -To simplify the program's option parsing, any value that the user provides -that is in the form "foo=bar" will also result in an environment variable -being set, eg `ANNEX_COMPUTE_passes=10` or `ANNEX_COMPUTE_--level=9`. - For security, the program should avoid exposing user input to the shell unprotected, or otherwise executing it. And when running a command, make sure that whatever user input is passed to it can result in only safe and expected behavior. +To simplify the program's option parsing, any value that the user provides +that is in the form "foo=bar" will also result in an environment variable +being set, eg `ANNEX_COMPUTE_passes=10` or `ANNEX_COMPUTE_--level=9`. + The program is run in a temporary directory, which will be cleaned up after it exits. Note that it may be run in a subdirectory of a temporary directory. This is done when `git-annex addcomputed` was run in a subdirectory @@ -58,6 +58,12 @@ line to stdout: OUTPUT file.jpeg +Then it can read a line from stdin. This will be a sanitized version of the +output filename. It's important to use that sanitized version to avoid path +traversal attacks, as well as problems like filenames that look like +dashed options. If there is a path traversal attack, the program's stdin will +be closed without a path being written to it. + The filename of the output file is both the filename in the program's temporary directory, and also the filename that will be added to the git-annex repository by `git-annex compute`. @@ -100,10 +106,9 @@ An example `git-annex-compute-foo` shell script follows: echo "INPUT $2" read input echo "OUTPUT $3" - # Prefixing with ./ makes sure that the output is treated as a - # filename, rather than a dashed option. - output="./$3" + read output echo REPRODUCIBLE + if [ -n "$input" ]; then mkdir -p "$(dirname "$output")" frobnicate --passes="$ANNEX_COMPUTE_passes" <"$input" >"$output" diff --git a/doc/special_remotes/compute/git-annex-compute-imageconvert b/doc/special_remotes/compute/git-annex-compute-imageconvert index 8edc6b8f24..16eb14da07 100755 --- a/doc/special_remotes/compute/git-annex-compute-imageconvert +++ b/doc/special_remotes/compute/git-annex-compute-imageconvert @@ -1,5 +1,5 @@ #!/bin/sh -# git-annex compute special remote program that uses imagemagic's convert +# git-annex compute remote program that uses imagemagic's convert # to convert one type of image format into another. Eg, jpeg to gif. # # Copyright 2025 Joey Hess; licenced under the GNU GPL version 3 or higher. @@ -14,10 +14,7 @@ fi echo "INPUT $1" read input echo "OUTPUT $2" - -# Prefixing with ./ makes sure that the output is treated as a -# filename, rather than a dashed option. -output="./$2" +read output if [ -n "$input" ]; then mkdir -p "$(dirname "$output")"