From 16f1e2466595da27a56c1a67846ba68a9692b365 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 14 Feb 2023 14:06:29 -0400 Subject: [PATCH] revert recent bug fix temporarily for release Decided this bug is not severe enough to delay the release until tomorrow, so this will be re-applied after the release. --- Assistant/MakeRepo.hs | 2 +- CHANGELOG | 3 --- Database/Keys.hs | 6 ++--- Git/Config.hs | 31 ++++++------------------ Git/Construct.hs | 16 ++++++------ Git/CurrentRepo.hs | 2 +- Remote/Git.hs | 2 +- doc/bugs/bare_remote_safe_directory.mdwn | 13 +++++++++- 8 files changed, 33 insertions(+), 42 deletions(-) diff --git a/Assistant/MakeRepo.hs b/Assistant/MakeRepo.hs index 06a0a659d0..bad4951b1d 100644 --- a/Assistant/MakeRepo.hs +++ b/Assistant/MakeRepo.hs @@ -57,7 +57,7 @@ initRepo True primary_assistant_repo dir desc mgroup = inDir dir $ do initRepo' desc mgroup {- Initialize the master branch, so things that expect - to have it will work, before any files are added. -} - unlessM (fromMaybe False . Git.Config.isBare <$> gitRepo) $ do + unlessM (Git.Config.isBare <$> gitRepo) $ do cmode <- annexCommitMode <$> Annex.getGitConfig void $ inRepo $ Git.Branch.commitCommand cmode (Git.Branch.CommitQuiet True) diff --git a/CHANGELOG b/CHANGELOG index ef5c220fdb..4a520d5459 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -24,9 +24,6 @@ git-annex (10.20230127) UNRELEASED; urgency=medium * info, enableremotemote, renameremote: Avoid a confusing message when more than one repository matches the user provided name. * info: Exit nonzero when the input is not supported. - * Fix more breakage caused by git's fix for CVE-2022-24765, this time - involving a remote that is a local bare repository not owned by the - current user. -- Joey Hess Mon, 06 Feb 2023 13:39:18 -0400 diff --git a/Database/Keys.hs b/Database/Keys.hs index 9f78578c12..9e1043edae 100644 --- a/Database/Keys.hs +++ b/Database/Keys.hs @@ -52,7 +52,7 @@ import Git.Sha import Git.CatFile import Git.Branch (writeTreeQuiet, update') import qualified Git.Ref -import Config +import qualified Git.Config import Config.Smudge import qualified Utility.RawFilePath as R @@ -176,7 +176,7 @@ getAssociatedFiles k = emptyWhenBare $ runReaderIO AssociatedTable $ - in a bare repository, but it might happen if a non-bare repo got - converted to bare. -} emptyWhenBare :: Annex [a] -> Annex [a] -emptyWhenBare a = ifM isBareRepo +emptyWhenBare a = ifM (Git.Config.isBare <$> gitRepo) ( return [] , a ) @@ -261,7 +261,7 @@ isInodeKnown i s = or <$> runReaderIO ContentTable - is an associated file. -} reconcileStaged :: Bool -> H.DbQueue -> Annex DbTablesChanged -reconcileStaged dbisnew qh = ifM isBareRepo +reconcileStaged dbisnew qh = ifM (Git.Config.isBare <$> gitRepo) ( return mempty , do gitindex <- inRepo currentIndexFile diff --git a/Git/Config.hs b/Git/Config.hs index 7e12a568e0..e788a2da55 100644 --- a/Git/Config.hs +++ b/Git/Config.hs @@ -133,28 +133,14 @@ store' k v repo = repo - based on the core.bare and core.worktree settings. -} updateLocation :: Repo -> IO Repo -updateLocation r@(Repo { location = LocalUnknown d }) = case isBare r of - Just True -> ifM (doesDirectoryExist (fromRawFilePath dotgit)) - ( updateLocation' r $ Local dotgit Nothing - , updateLocation' r $ Local d Nothing - ) - Just False -> mknonbare - {- core.bare not in config, probably because safe.directory - - did not allow reading the config -} - Nothing -> ifM (Git.Construct.isBareRepo (fromRawFilePath d)) - ( mkbare - , mknonbare - ) +updateLocation r@(Repo { location = LocalUnknown d }) + | isBare r = ifM (doesDirectoryExist (fromRawFilePath dotgit)) + ( updateLocation' r $ Local dotgit Nothing + , updateLocation' r $ Local d Nothing + ) + | otherwise = updateLocation' r $ Local dotgit (Just d) where dotgit = d P. ".git" - -- git treats eg ~/foo as a bare git repository located in - -- ~/foo/.git if ~/foo/.git/config has core.bare=true - mkbare = ifM (doesDirectoryExist (fromRawFilePath dotgit)) - ( updateLocation' r $ Local dotgit Nothing - , updateLocation' r $ Local d Nothing - ) - mknonbare = updateLocation' r $ Local dotgit (Just d) - updateLocation r@(Repo { location = l@(Local {}) }) = updateLocation' r l updateLocation r = return r @@ -226,9 +212,8 @@ boolConfig' :: Bool -> S.ByteString boolConfig' True = "true" boolConfig' False = "false" -{- Note that repoIsLocalBare is often better to use than this. -} -isBare :: Repo -> Maybe Bool -isBare r = isTrueFalse' =<< getMaybe coreBare r +isBare :: Repo -> Bool +isBare r = fromMaybe False $ isTrueFalse' =<< getMaybe coreBare r coreBare :: ConfigKey coreBare = "core.bare" diff --git a/Git/Construct.hs b/Git/Construct.hs index f82a3e91a1..89b1e1fafe 100644 --- a/Git/Construct.hs +++ b/Git/Construct.hs @@ -1,6 +1,6 @@ {- Construction of Git Repo objects - - - Copyright 2010-2023 Joey Hess + - Copyright 2010-2021 Joey Hess - - Licensed under the GNU AGPL version 3 or higher. -} @@ -23,7 +23,6 @@ module Git.Construct ( checkForRepo, newFrom, adjustGitDirFile, - isBareRepo, ) where #ifndef mingw32_HOST_OS @@ -217,7 +216,7 @@ checkForRepo :: FilePath -> IO (Maybe RepoLocation) checkForRepo dir = check isRepo $ check (checkGitDirFile (toRawFilePath dir)) $ - check (checkdir (isBareRepo dir)) $ + check isBareRepo $ return Nothing where check test cont = maybe cont (return . Just) =<< test @@ -226,17 +225,16 @@ checkForRepo dir = , return Nothing ) isRepo = checkdir $ - doesFileExist (dir ".git" "config") + gitSignature (".git" "config") <||> -- A git-worktree lacks .git/config, but has .git/gitdir. -- (Normally the .git is a file, not a symlink, but it can -- be converted to a symlink and git will still work; -- this handles that case.) - doesFileExist (dir ".git" "gitdir") - -isBareRepo :: FilePath -> IO Bool -isBareRepo dir = doesFileExist (dir "config") - <&&> doesDirectoryExist (dir "objects") + gitSignature (".git" "gitdir") + isBareRepo = checkdir $ gitSignature "config" + <&&> doesDirectoryExist (dir "objects") + gitSignature file = doesFileExist $ dir file -- Check for a .git file. checkGitDirFile :: RawFilePath -> IO (Maybe RepoLocation) diff --git a/Git/CurrentRepo.hs b/Git/CurrentRepo.hs index 54e05f4ac5..3b607d7bab 100644 --- a/Git/CurrentRepo.hs +++ b/Git/CurrentRepo.hs @@ -81,7 +81,7 @@ get = do } r <- Git.Config.read $ (newFrom loc) { gitDirSpecifiedExplicitly = True } - return $ if fromMaybe False (Git.Config.isBare r) + return $ if Git.Config.isBare r then r { location = (location r) { worktree = Nothing } } else r configure Nothing Nothing = giveup "Not in a git repository." diff --git a/Remote/Git.hs b/Remote/Git.hs index d42b0fa396..34fb902c56 100644 --- a/Remote/Git.hs +++ b/Remote/Git.hs @@ -304,7 +304,7 @@ tryGitConfigRead autoinit r hasuuid Right r' -> do -- Cache when http remote is not bare for -- optimisation. - unless (fromMaybe False $ Git.Config.isBare r') $ + unless (Git.Config.isBare r') $ setremote setRemoteBare False return r' Left err -> do diff --git a/doc/bugs/bare_remote_safe_directory.mdwn b/doc/bugs/bare_remote_safe_directory.mdwn index b05c490ec4..e21eca86a6 100644 --- a/doc/bugs/bare_remote_safe_directory.mdwn +++ b/doc/bugs/bare_remote_safe_directory.mdwn @@ -12,4 +12,15 @@ This is specific to bare git remotes, for non-bare it detects and warns that safe.directory is needed to use the remote. --[[Joey]] -> [[fixed|done]] --[[Joey]] +> What's causing this is that Git.Config.read is called +> on the repo, but git refuses to list the repo's config, +> so updateLocation does not see that the repo is bare +> when it checks isBare. And so it proceeds to set gitdir +> to the default non-bare "dir/.git" value. +> +> One way to deal with this would be to make isBare a tristate, +> since core.bare is not in the listed config at all. +> +> Or, make Git.Construct.fromPath detect when a repo is bare +> w/o parsing config, and indicate that in the Repo it +> generates.