Override safe.bareRepository for git remotes

Fix using git remotes that are bare when git is configured
with safe.bareRepository = explicit

Sponsored-by: Dartmouth College's DANDI project
This commit is contained in:
Joey Hess 2023-09-07 14:56:26 -04:00
parent cbfd214993
commit baf8e4f6ed
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
7 changed files with 37 additions and 19 deletions

View file

@ -3,6 +3,8 @@ git-annex (10.20230829) UNRELEASED; urgency=medium
* Fix more breakage caused by git's fix for CVE-2022-24765, this time * 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 involving a remote (either local or ssh) that is a repository not owned
by the current user. by the current user.
* Fix using git remotes that are bare when git is configured with
safe.bareRepository = explicit.
* 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

@ -124,11 +124,7 @@ 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
{- Since the path to the repository was specified let r' = r { repoPathSpecifiedExplicitly = True }
- 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' Git.Config.read r'
`catchIO` \_ -> do `catchIO` \_ -> do
hn <- fromMaybe "unknown" <$> getHostname hn <- fromMaybe "unknown" <$> getHostname

View file

@ -72,18 +72,21 @@ 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 ++ safedirparam params = addparams ++ explicitrepoparams
++ ["config", "--null", "--list"] ++ ["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 explicitrepoparams = if repoPathSpecifiedExplicitly repo
then
-- Use * rather than d, because git treats -- Use * rather than d, because git treats
-- "dir/" differently than "dir" when comparing for -- "dir/" differently than "dir" when comparing
-- safe.directory purposes. -- for safe.directory purposes.
then ["-c", "safe.directory=*"] [ "-c", "safe.directory=*"
, "-c", "safe.bareRepository=all"
]
else [] else []
git_config' p _ (Just hout) _ pid = git_config' p _ (Just hout) _ pid =
forceSuccessProcess p pid forceSuccessProcess p pid

View file

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

View file

@ -53,8 +53,11 @@ 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. -- Use when the path to the repository was specified explicitly,
, safeDirectory :: Bool -- eg in a git remote, and so it's safe to set
-- -c safe.directory=* and -c safe.bareRepository=all
-- when using this repository.
, repoPathSpecifiedExplicitly :: Bool
} deriving (Show, Eq, Ord) } deriving (Show, Eq, Ord)
newtype ConfigKey = ConfigKey S.ByteString newtype ConfigKey = ConfigKey S.ByteString

View file

@ -339,11 +339,7 @@ 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
{- Since the path to the repository was specified let r' = r { Git.repoPathSpecifiedExplicitly = True }
- 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' s <- newLocal r'
liftIO $ Annex.eval s $ check liftIO $ Annex.eval s $ check
`finally` quiesce True `finally` quiesce True

View file

@ -0,0 +1,18 @@
[[!comment format=mdwn
username="joey"
subject="""comment 4"""
date="2023-09-07T18:36:37Z"
content="""
Another related case is when git has been configured with
safe.bareRepository=explicit and the remote (either ssh or local)
is a bare repo. git-annex-shell will fail with the same misleading message,
and for a local repo, git-annex will also display the same misleading
message.
I think it also ought to override safe.bareRepository for such remotes,
because eg git pull works with such remotes. The point of
safe.bareRepository=explicit is not to prevent using bare remotes, but to
prevent things like shell prompts to accidentially use bare repos that are
eg, committed by a malicious attacker to a git repository, to avoid using
git configs that allow running arbitrary code.
"""]]