skip checkRepoConfigInaccessible when git directory specified explicitly
Fix a reversion that prevented git-annex from working in a repository when --git-dir or GIT_DIR is specified to relocate the git directory to somewhere else. (Introduced in version 10.20220525) checkRepoConfigInaccessible could still run git config --list, just passing --git-dir. It seems not necessary, because I know that passing --git-dir bypasses git's check for repo ownership. I suppose it might be that git eventually changes to check something about the ownership of the working tree, so passing --git-dir without --work-tree would still be worth doing. But for now this is the simple fix. Sponsored-by: Nicholas Golder-Manning on Patreon
This commit is contained in:
parent
d1467a9b8e
commit
8d26fdd670
6 changed files with 61 additions and 17 deletions
|
@ -23,6 +23,10 @@ git-annex (10.20220823) UNRELEASED; urgency=medium
|
||||||
that it had changed, due to only accepting the inode+mtime of one file
|
that it had changed, due to only accepting the inode+mtime of one file
|
||||||
(that was since modified or deleted) and not accepting the inode+mtime
|
(that was since modified or deleted) and not accepting the inode+mtime
|
||||||
of other duplicate files.
|
of other duplicate files.
|
||||||
|
* Fix a reversion that prevented git-annex from working in a
|
||||||
|
repository when --git-dir or GIT_DIR is specified to relocate the git
|
||||||
|
directory to somewhere else.
|
||||||
|
(Introduced in version 10.20220525)
|
||||||
|
|
||||||
-- Joey Hess <id@joeyh.name> Mon, 29 Aug 2022 15:03:04 -0400
|
-- Joey Hess <id@joeyh.name> Mon, 29 Aug 2022 15:03:04 -0400
|
||||||
|
|
||||||
|
|
|
@ -282,16 +282,20 @@ unset ck@(ConfigKey k) r = ifM (Git.Command.runBool ps r)
|
||||||
- repo.
|
- repo.
|
||||||
-}
|
-}
|
||||||
checkRepoConfigInaccessible :: Repo -> IO Bool
|
checkRepoConfigInaccessible :: Repo -> IO Bool
|
||||||
checkRepoConfigInaccessible r = do
|
checkRepoConfigInaccessible r
|
||||||
-- Cannot use gitCommandLine here because specifying --git-dir
|
-- When --git-dir or GIT_DIR is used to specify the git
|
||||||
-- will bypass the git security check.
|
-- directory, git does not check for CVE-2022-24765.
|
||||||
let p = (proc "git" ["config", "--local", "--list"])
|
| gitDirSpecifiedExplicitly r = return False
|
||||||
{ cwd = Just (fromRawFilePath (repoPath r))
|
| otherwise = do
|
||||||
, env = gitEnv r
|
-- Cannot use gitCommandLine here because specifying --git-dir
|
||||||
}
|
-- will bypass the git security check.
|
||||||
(out, ok) <- processTranscript' p Nothing
|
let p = (proc "git" ["config", "--local", "--list"])
|
||||||
if not ok
|
{ cwd = Just (fromRawFilePath (repoPath r))
|
||||||
then do
|
, env = gitEnv r
|
||||||
debug (DebugSource "Git.Config") ("config output: " ++ out)
|
}
|
||||||
return True
|
(out, ok) <- processTranscript' p Nothing
|
||||||
else return False
|
if not ok
|
||||||
|
then do
|
||||||
|
debug (DebugSource "Git.Config") ("config output: " ++ out)
|
||||||
|
return True
|
||||||
|
else return False
|
||||||
|
|
|
@ -277,5 +277,6 @@ newFrom l = Repo
|
||||||
, gitEnv = Nothing
|
, gitEnv = Nothing
|
||||||
, gitEnvOverridesGitDir = False
|
, gitEnvOverridesGitDir = False
|
||||||
, gitGlobalOpts = []
|
, gitGlobalOpts = []
|
||||||
|
, gitDirSpecifiedExplicitly = False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{- The current git repository.
|
{- The current git repository.
|
||||||
-
|
-
|
||||||
- Copyright 2012-2020 Joey Hess <id@joeyh.name>
|
- Copyright 2012-2022 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
- Licensed under the GNU AGPL version 3 or higher.
|
- Licensed under the GNU AGPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
@ -80,9 +80,10 @@ get = do
|
||||||
, worktree = Just curr
|
, worktree = Just curr
|
||||||
}
|
}
|
||||||
r <- Git.Config.read $ newFrom loc
|
r <- Git.Config.read $ newFrom loc
|
||||||
return $ if Git.Config.isBare r
|
let r' = r { gitDirSpecifiedExplicitly = True }
|
||||||
then r { location = (location r) { worktree = Nothing } }
|
return $ if Git.Config.isBare r'
|
||||||
else r
|
then r' { location = (location r) { worktree = Nothing } }
|
||||||
|
else r'
|
||||||
configure Nothing Nothing = giveup "Not in a git repository."
|
configure Nothing Nothing = giveup "Not in a git repository."
|
||||||
|
|
||||||
addworktree w r = changelocation r $ Local
|
addworktree w r = changelocation r $ Local
|
||||||
|
|
|
@ -51,6 +51,8 @@ data Repo = Repo
|
||||||
, gitEnvOverridesGitDir :: Bool
|
, gitEnvOverridesGitDir :: Bool
|
||||||
-- global options to pass to git when running git commands
|
-- global options to pass to git when running git commands
|
||||||
, gitGlobalOpts :: [CommandParam]
|
, gitGlobalOpts :: [CommandParam]
|
||||||
|
-- True only when --git-dir or GIT_DIR was used
|
||||||
|
, gitDirSpecifiedExplicitly :: Bool
|
||||||
} deriving (Show, Eq, Ord)
|
} deriving (Show, Eq, Ord)
|
||||||
|
|
||||||
newtype ConfigKey = ConfigKey S.ByteString
|
newtype ConfigKey = ConfigKey S.ByteString
|
||||||
|
|
|
@ -18,3 +18,35 @@ Simple test case:
|
||||||
|
|
||||||
failed
|
failed
|
||||||
|
|
||||||
|
And --debug shows:
|
||||||
|
|
||||||
|
[2022-09-20 14:17:56.238686901] (Utility.Process) process [1284622] read: git ["config","--local","--list"]
|
||||||
|
[2022-09-20 14:17:56.240836887] (Utility.Process) process [1284622] done ExitFailure 128
|
||||||
|
[2022-09-20 14:17:56.24107763] (Git.Config) config output: fatal: --local can only be used inside a git repository
|
||||||
|
|
||||||
|
So passing --git-dir to that command will make it succeeed. The problem
|
||||||
|
though is that passing --git-dir to that command also bypasses git's
|
||||||
|
fix for CVE-2022-24765. The command would even succeed if the directory
|
||||||
|
were owned by someone else then.
|
||||||
|
|
||||||
|
joey@darkstar:/tmp/foo>sudo chown -R root.root .
|
||||||
|
[sudo] password for joey:
|
||||||
|
joey@darkstar:/tmp/foo>git --git-dir=`pwd`/.dotfiles config --local --list
|
||||||
|
core.repositoryformatversion=0
|
||||||
|
core.filemode=true
|
||||||
|
core.bare=false
|
||||||
|
core.logallrefupdates=true
|
||||||
|
core.worktree=/tmp/foo
|
||||||
|
joey@darkstar:/tmp/foo>git config --local --list
|
||||||
|
fatal: --local can only be used inside a git repository
|
||||||
|
|
||||||
|
But, if the user runs git-annex with an explicit --git-dir,
|
||||||
|
it's actually ok for git-annex to bypass the CVE-2022-24765 check.
|
||||||
|
Because --git-dir actually bypasses that check.
|
||||||
|
|
||||||
|
So, the fix for this seems like it will involve it remembering
|
||||||
|
when the git repo was originally specified using --git-dir (or `GIT_DIR`),
|
||||||
|
and if so, guardSafeToUseRepo can skip the check, or pass --git-dir to
|
||||||
|
`git config --local --list`.
|
||||||
|
|
||||||
|
> [[fixed|done]] --[[Joey]]
|
||||||
|
|
Loading…
Reference in a new issue