From bee4122b80c167e0f79dc36550f55e1c2ae76d0e Mon Sep 17 00:00:00 2001 From: Neil Williams Date: Fri, 7 Jan 2022 13:50:28 +0000 Subject: Improve error handling in grab-cve-in-fix Catch and report on possible typos in changes entries to better support maintainers pre-checking the d.changelog entries before upload - as long as the .changes file is signed. --- bin/grab-cve-in-fix | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/bin/grab-cve-in-fix b/bin/grab-cve-in-fix index 9a7db822f9..98ea9cd476 100755 --- a/bin/grab-cve-in-fix +++ b/bin/grab-cve-in-fix @@ -52,6 +52,8 @@ from debian.deb822 import Changes import setup_paths # noqa # pylint: disable=unused-import from sectracker.parsers import ( sourcepackages, + FlagAnnotation, + StringAnnotation, PackageAnnotation, Bug, cvelist, @@ -87,6 +89,23 @@ class ParseChanges: for bug in data: if bug.header.name == cve: self.bugs[cve] = bug + package_checks = {} + cve_notes = {} + for cve, bug in self.bugs.items(): + self.logger.info("%s: %s", bug.header.name, bug.header.description) + for line in bug.annotations: + if isinstance(line, PackageAnnotation): + package_checks.setdefault(cve, []) + package_checks[cve].append(line.package) + if isinstance(line, StringAnnotation) or isinstance(line, FlagAnnotation): + cve_notes.setdefault(cve, []) + cve_notes[cve].append(line.type) + if cve not in package_checks: + self.logger.error("CVE %s is not attributed to a Debian package: %s", cve, cve_notes.get(cve, "")) + elif self.source_package not in package_checks[cve]: + self.logger.warning( + "%s is listed against %s, not %s", cve, list(set(package_checks[cve])), self.source_package + ) if not self.cves: self.logger.warning( "no CVEs found in the changes output " "for %s %s", @@ -126,6 +145,10 @@ class ParseChanges: 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. + + A typo in the CVE ID *may* cause a CVE to be declared as + fixed in the wrong source package. This is complicated by + the need to allow for embedded copies and removed packages. """ modified = [] cve_file = f"{self.source_package}.list" @@ -134,10 +157,10 @@ class ParseChanges: 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]", + "%s was not found in the Security Tracker CVE list! Check %s%s - " + "possible typo in the package changelog? Check the list of CVEs " + "in the security tracker and use this script again, in offline mode." + " ./bin grab-cve-in-fix --src %s --cves corrected-cve", cve, self.tracker_base, self.source_package, @@ -150,6 +173,11 @@ class ParseChanges: if line.release: # only update unstable continue if line.package != self.source_package: + self.logger.info( + "Ignoring %s annotation for %s", + cve, + line.package, + ) continue # allow for removed, old or alternate pkg names if line.version: vcompare = apt_pkg.version_compare( # pylint: disable=c-extension-no-member @@ -302,12 +330,15 @@ class ParseDDStdIn(ParseChanges): MARKER = "-----BEGIN PGP SIGNED MESSAGE-----" def parse(self): - self.logger.info("Retrieving data from debian-devel-changes archive...") + self.logger.info("Retrieving data STDIN ...") content = sys.stdin.read() for line in content.splitlines(): if not self.parsed and not line.startswith(self.MARKER): continue self.parsed.append(line) + if not self.parsed: + self.logger.warning("Unable to find PGP marker - unsigned content?") + return 1 self._read_changes() self._read_cvelist() self.add_unstable_version() -- cgit v1.2.3