set safe.directory when getting config for git-annex-shell or git remotes

Fix more breakage caused by git's fix for CVE-2022-24765, this time
involving a remote (either local or ssh) that is a repository not owned by
the current user.

Sponsored-by: Dartmouth College's DANDI project
This commit is contained in:
Joey Hess 2023-09-07 14:36:16 -04:00
parent 32cb2bd3fa
commit cbfd214993
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
10 changed files with 75 additions and 4 deletions

View file

@ -1,5 +1,8 @@
git-annex (10.20230829) UNRELEASED; urgency=medium git-annex (10.20230829) UNRELEASED; urgency=medium
* Fix more breakage caused by git's fix for CVE-2022-24765, this time
involving a remote (either local or ssh) that is a repository not owned
by the current user.
* Removed the vendored git-lfs and the GitLfs build flag. * Removed the vendored git-lfs and the GitLfs build flag.
* Fix linker optimisation in linux standalone tarballs. * Fix linker optimisation in linux standalone tarballs.

View file

@ -1,6 +1,6 @@
{- git-annex-shell main program {- git-annex-shell main program
- -
- Copyright 2010-2021 Joey Hess <id@joeyh.name> - Copyright 2010-2023 Joey Hess <id@joeyh.name>
- -
- Licensed under the GNU AGPL version 3 or higher. - Licensed under the GNU AGPL version 3 or higher.
-} -}
@ -18,6 +18,7 @@ import CmdLine.GitAnnexShell.Checks
import CmdLine.GitAnnexShell.Fields import CmdLine.GitAnnexShell.Fields
import Remote.GCrypt (getGCryptUUID) import Remote.GCrypt (getGCryptUUID)
import P2P.Protocol (ServerMode(..)) import P2P.Protocol (ServerMode(..))
import Git.Types
import qualified Command.ConfigList import qualified Command.ConfigList
import qualified Command.NotifyChanges import qualified Command.NotifyChanges
@ -123,7 +124,12 @@ builtin cmd dir params = do
mkrepo = do mkrepo = do
r <- Git.Construct.repoAbsPath (toRawFilePath dir) r <- Git.Construct.repoAbsPath (toRawFilePath dir)
>>= Git.Construct.fromAbsPath >>= Git.Construct.fromAbsPath
Git.Config.read r {- Since the path to the repository was specified
- explicitly, CVE-2022-24765 is not a concern,
- so tell git to treat the repository directory as safe.
-}
let r' = r { safeDirectory = True }
Git.Config.read r'
`catchIO` \_ -> do `catchIO` \_ -> do
hn <- fromMaybe "unknown" <$> getHostname hn <- fromMaybe "unknown" <$> getHostname
giveup $ "failed to read git config of git repository in " ++ hn ++ " on " ++ dir ++ "; perhaps this repository is not set up correctly or has moved" giveup $ "failed to read git config of git repository in " ++ hn ++ " on " ++ dir ++ "; perhaps this repository is not set up correctly or has moved"

View file

@ -72,12 +72,19 @@ read' repo = go repo
go _ = assertLocal repo $ error "internal" go _ = assertLocal repo $ error "internal"
git_config addparams d = withCreateProcess p (git_config' p) git_config addparams d = withCreateProcess p (git_config' p)
where where
params = addparams ++ ["config", "--null", "--list"] params = addparams ++ safedirparam
++ ["config", "--null", "--list"]
p = (proc "git" params) p = (proc "git" params)
{ cwd = Just (fromRawFilePath d) { cwd = Just (fromRawFilePath d)
, env = gitEnv repo , env = gitEnv repo
, std_out = CreatePipe , std_out = CreatePipe
} }
safedirparam = if safeDirectory repo
-- Use * rather than d, because git treats
-- "dir/" differently than "dir" when comparing for
-- safe.directory purposes.
then ["-c", "safe.directory=*"]
else []
git_config' p _ (Just hout) _ pid = git_config' p _ (Just hout) _ pid =
forceSuccessProcess p pid forceSuccessProcess p pid
`after` `after`

View file

@ -287,5 +287,6 @@ newFrom l = Repo
, gitEnvOverridesGitDir = False , gitEnvOverridesGitDir = False
, gitGlobalOpts = [] , gitGlobalOpts = []
, gitDirSpecifiedExplicitly = False , gitDirSpecifiedExplicitly = False
, safeDirectory = False
} }

View file

@ -53,6 +53,8 @@ data Repo = Repo
, gitGlobalOpts :: [CommandParam] , gitGlobalOpts :: [CommandParam]
-- True only when --git-dir or GIT_DIR was used -- True only when --git-dir or GIT_DIR was used
, gitDirSpecifiedExplicitly :: Bool , gitDirSpecifiedExplicitly :: Bool
-- Set -c safe.directory when using this repository.
, safeDirectory :: Bool
} deriving (Show, Eq, Ord) } deriving (Show, Eq, Ord)
newtype ConfigKey = ConfigKey S.ByteString newtype ConfigKey = ConfigKey S.ByteString

View file

@ -339,7 +339,12 @@ tryGitConfigRead autoinit r hasuuid
warning $ UnquotedString $ "Remote " ++ Git.repoDescribe r ++ warning $ UnquotedString $ "Remote " ++ Git.repoDescribe r ++
": " ++ show e ": " ++ show e
Annex.getState Annex.repo Annex.getState Annex.repo
s <- newLocal r {- Since the path to the repository was specified
- explicitly, CVE-2022-24765 is not a concern,
- so tell git to treat the repository directory as safe.
-}
let r' = r { Git.safeDirectory = True }
s <- newLocal r'
liftIO $ Annex.eval s $ check liftIO $ Annex.eval s $ check
`finally` quiesce True `finally` quiesce True

View file

@ -42,3 +42,5 @@ so, ideally `git annex enableremote` should provide a similar diagnostic output
[[!tag projects/dandi]] [[!tag projects/dandi]]
``` ```
> [[fixed|done]] --[[Joey]]

View file

@ -0,0 +1,24 @@
[[!comment format=mdwn
username="joey"
subject="""comment 1"""
date="2023-09-07T17:01:41Z"
content="""
I wonder if it even makes sense for git-annex-shell to replicate this git
security check, or would it be better for it to instruct git to trust the
repository, so it can be used on it?
git's CVE-2022-24765 involves a malicious creation of a .git repository
above the victim's cwd, with a .git/config that causes things like eg shell
prompts that run git to execute attacker-controlled commands.
git-annex-shell commands all take the directory that the repository is
in, and uses that repository. So it doesn't traverse above looking for
other .git directories.
And, `git clone` will happily clone a remote repsository that's owned
by another user, including over ssh. And pull and push etc work with such a
remote. So git-annex-shell should too.
(For that matter, other git-annex-shell commands do work, it's only the
command that reads the git config that fails to work.)
"""]]

View file

@ -0,0 +1,13 @@
[[!comment format=mdwn
username="joey"
subject="""comment 2"""
date="2023-09-07T18:21:30Z"
content="""
Closely related, when a local repo is owned by someone else, cloning it and
using it as a git-annex remote also fails, at the same config listing
stage.
I think the same reasoning applies to that, the path to the repo is
explicitly specified in the remote url, so it should treat it as a safe
repo for the purposes of listing its config.
"""]]

View file

@ -0,0 +1,8 @@
[[!comment format=mdwn
username="joey"
subject="""comment 3"""
date="2023-09-07T18:32:57Z"
content="""
Basically the same fix works for both the ssh remote and the local
remote cases.
"""]]