diff options
author | Neil Williams <codehelp@debian.org> | 2022-01-06 14:04:39 +0000 |
---|---|---|
committer | Neil Williams <codehelp@debian.org> | 2022-01-27 09:08:15 +0000 |
commit | 5c78a9edc92adac0fb04c57e3ae96df53d7fe997 (patch) | |
tree | be74b5e674f4bdd38843d7419062d55da23f33b3 /bin/grab-cve-in-fix | |
parent | 23c1259dafe643660d9fc92cb9bf96af67cd7241 (diff) |
Update grab-cve-in-fix for known examples
Support catching errors in the d.changelog
Add support for forcing a specific version
Fix typo in new support in bin/merge-cve-files
Update support in update-vuln to insert new
PackageAnnotations in specific order.
Diffstat (limited to 'bin/grab-cve-in-fix')
-rwxr-xr-x | bin/grab-cve-in-fix | 82 |
1 files changed, 73 insertions, 9 deletions
diff --git a/bin/grab-cve-in-fix b/bin/grab-cve-in-fix index cabda5584a..5d6068f54d 100755 --- a/bin/grab-cve-in-fix +++ b/bin/grab-cve-in-fix @@ -11,7 +11,7 @@ grab-cve-in-fix - #1001451 """ # -# Copyright 2021 Neil Williams <codehelp@debian.org> +# Copyright 2021-2022 Neil Williams <codehelp@debian.org> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -43,6 +43,9 @@ import re import sys import requests +# depends on python3-apt +import apt_pkg + # depends on python3-debian from debian.deb822 import Changes @@ -66,6 +69,9 @@ class ParseChanges: self.bugs = {} self.parsed = [] self.unstable_version = None + self.tracker_base = ( + "https://security-tracker.debian.org/tracker/source-package/" + ) self.logger = logging.getLogger("grab-cve-in-fix") self.logger.setLevel(logging.DEBUG) # console logging @@ -74,6 +80,7 @@ class ParseChanges: formatter = logging.Formatter("%(name)s - %(levelname)s - %(message)s") ch.setFormatter(formatter) self.logger.addHandler(ch) + apt_pkg.init_system() def _read_cvelist(self): os.chdir(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) @@ -114,12 +121,31 @@ class ParseChanges: Writes out a CVE file snippet with the filename: ./<src_package>.list Fails if the file already exists. + + Prints error if any of the listed CVEs are not found + for the specified source_package. + + If a new version is set, the fixed version for the CVE will + be updated to that version. Uses python3-apt to only update + if the version is declared, by apt, to be newer. """ modified = [] cve_file = f"{self.source_package}.list" cves = sorted(set(self.cves)) cves.reverse() for cve in cves: + if cve not in self.bugs: + self.logger.error( + "%s was not found in the CVE list! Check %s%s " + "Possible typo in the package changelog? " + "Check the list of CVEs and use this script again, in offline mode." + " ./bin g--src %s --cves [corrected-cve]", + cve, + self.tracker_base, + self.source_package, + self.source_package, + ) + continue for line in self.bugs[cve].annotations: if not isinstance(line, PackageAnnotation): continue # skip notes etc. @@ -128,12 +154,33 @@ class ParseChanges: if line.package != self.source_package: continue # allow for removed, old or alternate pkg names if line.version: - self.logger.info( - "%s already has annotation for - %s %s", - cve, - self.source_package, - line.version, - ) + vc = apt_pkg.version_compare(line.version, self.unstable_version) + if vc < 0: + self.logger.info( + "Updating %s to %s", line.version, self.unstable_version + ) + mod_line = line._replace(version=self.unstable_version) + index = self.bugs[cve].annotations.index(line) + bug_list = list(self.bugs[cve].annotations) + bug_list[index] = mod_line + mod_bug = Bug( + self.bugs[cve].file, self.bugs[cve].header, tuple(bug_list) + ) + modified.append(mod_bug) + elif vc > 0: + self.logger.error( + "%s is listed as fixed in %s which is newer than %s", + cve, + line.version, + self.unstable_version, + ) + else: + self.logger.info( + "%s already has annotation for - %s %s", + cve, + self.source_package, + line.version, + ) else: mod_line = line._replace(version=self.unstable_version) index = self.bugs[cve].annotations.index(line) @@ -165,6 +212,18 @@ class ParseSources(ParseChanges): """Read latest version in unstable from updated local Sources files""" def parse(self): + """ + Support to pick up unstable_version from the local packages cache. + + Also supports explicitly setting the version for times when + the package has received an unrelated update in unstable. + """ + if self.unstable_version: + self.logger.info("Using forced version: %s", self.unstable_version) + self._read_cvelist() + self.add_unstable_version() + return 0 + self.logger.info("Retrieving data from local packages data...") if not self.source_package or not self.cves: self.logger.error("for offline use, specify both --src and --cves options") @@ -303,6 +362,10 @@ def main(): "--src", help="Source package name to look up version in local packages files" ) offline.add_argument( + "--force-version", + help="Explicitly set the fixed version, in case sid has moved ahead.", + ) + offline.add_argument( "--cves", nargs="*", help="CVE ID tag with version from local packages files" ) args = parser.parse_args() @@ -320,9 +383,10 @@ def main(): data = ParseSources(pkg_dir) data.source_package = args.src data.cves = args.cves + if args.force_version: + data.unstable_version = args.force_version return data.parse() - self.logger.error("Unable to parse local package data!") - self.logger.error("Try running 'make update-packages'") + self.logger.error("Unable to parse package data!") return -1 |