support git files as input to computations

Using GIT keys, like are used when exporting git files to special
remotes. Except here the GIT key refers to a file checked into the git
repo.

Note that, since the compute remote uses catObject to get the content,
a symlink that is checked into git does not get followed. This is important
for security, because following a symlink and adding the content to the
repo as an annex object would allow exfiltrating content from outside
the repository.

Instead, the behavior with a symlink is to run the computation on the
symlink target. This may turn out to be confusing, and it might be worth
addcomputed checking if the file in git is a symlink and erroring out.
Or it could follow symlinks as long as the destination is a file in the
repisitory.
This commit is contained in:
Joey Hess 2025-03-03 11:59:04 -04:00
parent 6ebab7fb00
commit a0d6a6ea2a
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
5 changed files with 56 additions and 31 deletions

View file

@ -35,6 +35,8 @@ import Annex.SpecialRemote.Config
import Annex.UUID
import Annex.Content
import Annex.Tmp
import Annex.GitShaKey
import Annex.CatFile
import Logs.MetaData
import Logs.EquivilantKeys
import Utility.Metered
@ -43,10 +45,11 @@ import Utility.Env
import Utility.Tmp.Dir
import Utility.Url
import Utility.MonotonicClock
import qualified Git
import qualified Utility.SimpleProtocol as Proto
import Types.Key
import Backend
import qualified Git
import qualified Utility.FileIO as F
import qualified Utility.SimpleProtocol as Proto
import Network.HTTP.Types.URI
import Data.Time.Clock
@ -341,7 +344,7 @@ runComputeProgram
:: ComputeProgram
-> ComputeState
-> ImmutableState
-> (OsPath -> Annex (Key, Maybe OsPath))
-> (OsPath -> Annex (Key, Maybe (Either Git.Sha OsPath)))
-> (ComputeState -> OsPath -> NominalDiffTime -> Annex v)
-> Annex v
runComputeProgram (ComputeProgram program) state (ImmutableState immutablestate) getinputcontent cont =
@ -395,12 +398,17 @@ runComputeProgram (ComputeProgram program) state (ImmutableState immutablestate)
let knowninput = M.member f' (computeInputs state')
checksafefile tmpdir subdir f' "input"
checkimmutable knowninput "inputting" f' $ do
(k, mp) <- getinputcontent f'
mp' <- liftIO $ maybe (pure Nothing)
(Just <$$> relPathDirToFile subdir)
mp
(k, inputcontent) <- getinputcontent f'
mp <- case inputcontent of
Nothing -> pure Nothing
Just (Right f'') -> liftIO $
Just <$> relPathDirToFile subdir f''
Just (Left gitsha) -> do
liftIO . F.writeFile (subdir </> f')
=<< catObject gitsha
return (Just f')
liftIO $ hPutStrLn (stdinHandle p) $
maybe "" fromOsPath mp'
maybe "" fromOsPath mp
liftIO $ hFlush (stdinHandle p)
return $ if immutablestate
then state
@ -467,10 +475,13 @@ computeKey rs (ComputeProgram program) k _af dest p vc =
getinputcontent state f =
case M.lookup (fromOsPath f) (computeInputs state) of
Just inputkey -> do
obj <- calcRepo (gitAnnexLocation inputkey)
-- XXX get input object when not present
return (inputkey, Just obj)
Just inputkey -> case keyGitSha inputkey of
Nothing -> do
obj <- calcRepo (gitAnnexLocation inputkey)
-- XXX get input object when not present
return (inputkey, Just (Right obj))
Just gitsha ->
return (inputkey, Just (Left gitsha))
Nothing -> error "internal"
computeskey state =