git style filename quoting for giveup

When the filenames are part of the git repository or other files that
might have attacker-controlled names, quote them in error messages.

This is fairly complete, although I didn't do the one in
Utility.DirWatcher.INotify.hs because that doesn't have access to
Git.Filename or Annex.

But it's also quite possible I missed some. And also while scanning for
these, I found giveup used with other things that could be attacker
controlled to contain control characters (eg Keys). So, I'm thinking
it would also be good for giveup to just filter out control characters.
This commit is then not the only line of defence, but just good
formatting when git-annex displays a filename in an error message.

Sponsored-by: Kevin Mueller on Patreon
This commit is contained in:
Joey Hess 2023-04-10 12:56:45 -04:00
parent da83652c76
commit 063c00e4f7
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
8 changed files with 79 additions and 30 deletions

View file

@ -5,6 +5,8 @@
- Licensed under the GNU AGPL version 3 or higher.
-}
{-# LANGUAGE OverloadedStrings #-}
module Command.Reinject where
import Command
@ -15,6 +17,8 @@ import Types.KeySource
import Utility.Metered
import Annex.WorkTree
import qualified Git
import qualified Annex
import Git.Filename
cmd :: Command
cmd = withAnnexOptions [backendOption] $
@ -48,13 +52,20 @@ startSrcDest ps@(src:dest:[])
| otherwise = notAnnexed src' $
lookupKey (toRawFilePath dest) >>= \case
Just k -> go k
Nothing -> giveup $ src ++ " is not an annexed file"
Nothing -> do
qp <- coreQuotePath <$> Annex.getGitConfig
giveup $ decodeBS $ quote qp $ QuotedPath src'
<> " is not an annexed file"
where
src' = toRawFilePath src
go key = starting "reinject" ai si $
ifM (verifyKeyContent key src')
( perform src' key
, giveup $ src ++ " does not have expected content of " ++ dest
, do
qp <- coreQuotePath <$> Annex.getGitConfig
giveup $ decodeBS $ quote qp $ QuotedPath src'
<> " does not have expected content of "
<> QuotedPath (toRawFilePath dest)
)
ai = ActionItemOther (Just (QuotedPath src'))
si = SeekInput ps
@ -81,7 +92,11 @@ notAnnexed src a =
ifM (fromRepo Git.repoIsLocalBare)
( a
, lookupKey src >>= \case
Just _ -> giveup $ "cannot used annexed file as src: " ++ fromRawFilePath src
Just _ -> do
qp <- coreQuotePath <$> Annex.getGitConfig
giveup $ decodeBS $ quote qp $
"cannot used annexed file as src: "
<> QuotedPath src
Nothing -> a
)