indicate if a CVE has been patched

This commit is contained in:
Ryan Mulligan 2019-10-28 07:41:45 -07:00
parent 78fe5fe745
commit 3741b7e634
4 changed files with 52 additions and 9 deletions

View File

@ -50,9 +50,15 @@ data CVE =
deriving (Show, Eq, Ord)
-- | cve list item
cveLI :: CVE -> Text
cveLI c =
"- [" <> cveID c <> "](https://nvd.nist.gov/vuln/detail/" <> cveID c <> ")"
cveLI :: CVE -> Bool -> Text
cveLI c patched =
"- [" <>
cveID c <> "](https://nvd.nist.gov/vuln/detail/" <> cveID c <> ")" <> p
where
p =
if patched
then " (patched)"
else ""
-- This decodes an entire CPE string and related attributes, but we only use
-- cpeVulnerable, cpeProduct, cpeVersion and cpeMatcher.

View File

@ -117,9 +117,11 @@ main = do
Right t -> T.putStrLn t
UpdateVulnDB -> withVulnDB $ \_conn -> pure ()
CheckAllVulnerable -> do
setupNixpkgs undefined
updates <- T.readFile "packages-to-update.txt"
cveAll (Options undefined undefined) updates
CheckVulnerable productID oldVersion newVersion -> do
setupNixpkgs undefined
report <-
cveReport
(UpdateEnv productID oldVersion newVersion (Options False undefined))

View File

@ -26,6 +26,9 @@ module Nix
, resultLink
, sha256Zero
, version
, getPatches
, hasPatchNamed
, Raw(..)
) where
import OurPrelude
@ -54,7 +57,7 @@ nixEvalET raw expr =
ourReadProcessInterleaved_
(proc "nix" (["eval", "-f", "."] <> rawOpt raw <> [T.unpack expr])) &
fmapRT T.strip &
overwriteErrorT ("nix eval failed for " <> expr <> " ")
overwriteErrorT ("nix eval failed for \"" <> expr <> "\"")
-- Error if the "new version" is actually newer according to nix
assertNewerVersion :: MonadIO m => UpdateEnv -> ExceptT Text m ()
@ -273,3 +276,15 @@ getHashFromBuild =
version :: MonadIO m => ExceptT Text m Text
version = ourReadProcessInterleaved_ "nix --version"
getPatches :: MonadIO m => Text -> ExceptT Text m Text
getPatches attrPath =
nixEvalET
NoRaw
("(let pkgs = import ./. {}; in (map (p: p.name) pkgs." <>
attrPath <> ".patches))")
hasPatchNamed :: MonadIO m => Text -> Text -> ExceptT Text m Bool
hasPatchNamed attrPath name = do
ps <- getPatches attrPath
return $ name `T.isInfixOf` ps

View File

@ -10,12 +10,13 @@ module Update
, cveReport
, cveAll
, sourceGithubAll
, addPatched
) where
import OurPrelude
import qualified Blacklist
import CVE (cveLI)
import CVE (CVE, cveID, cveLI)
import qualified Check
import Control.Concurrent
import qualified Data.ByteString.Lazy.Char8 as BSL
@ -382,11 +383,27 @@ assertNotUpdatedOn updateEnv derivationFile branch = do
derivationContents <- fmapLT tshow $ tryIO $ T.readFile derivationFile
Nix.assertOldVersionOn updateEnv branch derivationContents
addPatched :: Text -> Set CVE -> IO [(CVE, Bool)]
addPatched attrPath set = do
let list = S.toList set
forM
list
(\cve -> do
patched <- runExceptT $ Nix.hasPatchNamed attrPath (cveID cve)
let p =
case patched of
Left _ -> False
Right r -> r
return (cve, p))
cveReport :: UpdateEnv -> IO Text
cveReport updateEnv =
withVulnDB $ \conn
-- TODO try other heuristics for project id
-- example false positive in current plan "vault"
-- def product_candidates(self):
-- return {self.pname, self.pname.replace('-', '_')}
-- TODO add fixup for Vendor
-> do
oldCVEs <-
S.fromList <$> getCVEs conn (packageName updateEnv) (oldVersion updateEnv)
@ -399,10 +416,13 @@ cveReport updateEnv =
if t == T.empty
then "none"
else t
toMkdownList = S.toList >>> fmap cveLI >>> T.unlines >>> ifEmptyNone
fixedList = toMkdownList inOldButNotNew
newList = toMkdownList inNewButNotOld
unresolvedList = toMkdownList inBoth
inOldButNotNew' <- addPatched (packageName updateEnv) inOldButNotNew
inNewButNotOld' <- addPatched (packageName updateEnv) inNewButNotOld
inBoth' <- addPatched (packageName updateEnv) inBoth
let toMkdownList = fmap (uncurry cveLI) >>> T.unlines >>> ifEmptyNone
fixedList = toMkdownList inOldButNotNew'
newList = toMkdownList inNewButNotOld'
unresolvedList = toMkdownList inBoth'
if fixedList == "none" && unresolvedList == "none" && newList == "none"
then return ""
else return