SHA: Add a runtime sanity check that sha commands output something that appears to be a real sha.

This after fielding a bug where git-annex was built with a sha256 program
whose output checked out, but was then run with one that output lines
like:

SHA256 (file) = <sha here>

Which it then parsed as having a SHA256 of "SHA256"!

Now the output of the command is required to be of the right length,
and contain only the right characters.
This commit is contained in:
Joey Hess 2013-05-07 20:19:37 -04:00
parent 53f1d36b35
commit cda0ed5d25
2 changed files with 24 additions and 2 deletions

View file

@ -57,8 +57,9 @@ shaN shasize file filesize = do
showAction "checksum" showAction "checksum"
case shaCommand shasize filesize of case shaCommand shasize filesize of
Left sha -> liftIO $ sha <$> L.readFile file Left sha -> liftIO $ sha <$> L.readFile file
Right command -> liftIO $ parse command . lines <$> Right command -> liftIO $
readsha command (toCommand [File file]) sanitycheck command . parse command . lines <$>
readsha command (toCommand [File file])
where where
parse command [] = bad command parse command [] = bad command
parse command (l:_) parse command (l:_)
@ -69,6 +70,7 @@ shaN shasize file filesize = do
where where
sha = fst $ separate (== ' ') l sha = fst $ separate (== ' ') l
bad command = error $ command ++ " parse error" bad command = error $ command ++ " parse error"
{- sha commands output the filename, so need to set fileEncoding -} {- sha commands output the filename, so need to set fileEncoding -}
readsha command args = readsha command args =
withHandle StdoutHandle createProcessSuccess p $ \h -> do withHandle StdoutHandle createProcessSuccess p $ \h -> do
@ -79,6 +81,24 @@ shaN shasize file filesize = do
where where
p = (proc command args) { std_out = CreatePipe } p = (proc command args) { std_out = CreatePipe }
{- Check that we've correctly parsing the output of the command,
- by making sure the sha we read is of the expected length. -}
sanitycheck command sha
| length sha /= expectedlen =
error $ "Failed to parse the output of " ++ command
| any (`notElem` "0123456789abcdef") sha' =
error $ "Unexpected character in output of " ++ command ++ "\"" ++ sha ++ "\""
| otherwise = sha'
where
sha' = map toLower sha
expectedlen = case shasize of
1 -> 40
256 -> 64
512 -> 128
224 -> 56
384 -> 96
_ -> 0
shaCommand :: SHASize -> Integer -> Either (L.ByteString -> String) String shaCommand :: SHASize -> Integer -> Either (L.ByteString -> String) String
shaCommand shasize filesize shaCommand shasize filesize
| shasize == 1 = use SysConfig.sha1 sha1 | shasize == 1 = use SysConfig.sha1 sha1

2
debian/changelog vendored
View file

@ -15,6 +15,8 @@ git-annex (4.20130502) UNRELEASED; urgency=low
* git-annex-shell: Ensure that received files can be read. Files * git-annex-shell: Ensure that received files can be read. Files
transferred from some Android devices may have very broken permissions transferred from some Android devices may have very broken permissions
as received. as received.
* SHA: Add a runtime sanity check that sha commands output something
that appears to be a real sha.
-- Joey Hess <joeyh@debian.org> Thu, 02 May 2013 20:39:19 -0400 -- Joey Hess <joeyh@debian.org> Thu, 02 May 2013 20:39:19 -0400