Author: fw Date: 2005-09-16 19:52:34 +0000 (Fri, 16 Sep 2005) New Revision: 2025 Modified: lib/python/security_db.py Log: lib/python/security_db.py (DB._parseFile): Record architectures. (DB._readSourcePackages): Update accordingly. (DB._readBinaryPackages): Use "Architecture: all" if possible, to cut down the database size a bit. (DB.calculateVulnerabilities): Synthesize source package status from binary package annotations. Modified: lib/python/security_db.py ==================================================================--- lib/python/security_db.py 2005-09-16 18:30:15 UTC (rev 2024) +++ lib/python/security_db.py 2005-09-16 19:52:34 UTC (rev 2025) @@ -293,6 +293,7 @@ for pkg in packages: pkg_name = None pkg_version = None + pkg_arch = None pkg_source = None pkg_source_version = None for (name, contents) in pkg: @@ -307,6 +308,8 @@ + ''invalid source package %s'') % (pkg_name, `contents`)) (pkg_source, pkg_source_version) = match.groups() + elif name == "Architecture": + pkg_arch = contents if pkg_name is None: raise SyntaxError\ ("package record does not contain package name") @@ -314,7 +317,11 @@ raise SyntaxError\ ("package record for %s does not contain version" % pkg_name) - data.append((pkg_name, pkg_version, + if pkg_arch is None: + raise SyntaxError\ + ("package record for %s lacks Architecture: field" + % pkg_name) + data.append((pkg_name, pkg_version, pkg_arch, pkg_source, pkg_source_version)) return data @@ -378,7 +385,7 @@ self._clearVersions(cursor) def gen(): - for (name, version, source, source_version) in parsed: + for (name, version, archs, source, source_version) in parsed: assert source is None assert source_version is None yield name, release, subrelease, archive, version @@ -408,18 +415,20 @@ (release, subrelease, archive, architecture) = match.groups() (unch, parsed) = self._parseFile(cursor, filename) unchanged = unchanged and unch - for (name, version, source, source_version) in parsed: + for (name, version, arch, source, source_version) in parsed: if source is None: source = name if source_version is None: source_version = version - + if arch <> ''all'' and arch <> architecture: + raise ValueError, ("invalid architecture %s for package %s" + % (arch, name)) key = (name, release, subrelease, archive, version, source, source_version) if packages.has_key(key): - packages[key][architecture] = 1 + packages[key][arch] = 1 else: - packages[key] = {architecture : 1} + packages[key] = {arch : 1} if unchanged: if self.verbose: @@ -615,7 +624,7 @@ % (b.source_file, b.source_line, target)) if errors: - raise InsertErrors(errors) + raise InsertError(errors) if self.verbose: print " finished" @@ -769,6 +778,7 @@ WHERE package_kind = ''unknown'' AND EXISTS (SELECT * FROM binary_packages AS p WHERE p.name = package_notes.package)""") + for (bug_name, s_package, b_package) in list(cursor.execute( """SELECT DISTINCT s.bug_name, s.package, b.package FROM package_notes AS s, package_notes AS b, binary_packages AS p @@ -784,6 +794,27 @@ result.append("%s:%d: binary package: %s" % (b.source_file, b.source_line, b_package)) + if False: + # The following check looks useful, but there are + # situations where we want to be very explicit about + # vulnerable binary packges (see CAN-2004-0914 and + # DSA-573-1). + for (bug_name, source_package, b1, b2) in list(cursor.execute( + """SELECT n.bug_name, b.source, + MIN(n.package) AS n1, MAX(n.package) AS n2 + FROM package_notes AS n, binary_packages AS b + WHERE n.package_kind = ''binary'' AND b.name = n.package + GROUP BY n.bug_name, b.source + HAVING n1 <> n2""")): + b = bugs.BugFromDB(cursor, bug_name) + result.append( + "%s:%d: source package %s is referenced multiple times:" + % (b.source_file, b.source_line, source_package)) + result.append("%s:%d: binary package: %s" + % (b.source_file, b.source_line, b1)) + result.append("%s:%d: binary package: %s" + % (b.source_file, b.source_line, b2)) + for (bug_name, pkg_name, release) in list(cursor.execute( """SELECT DISTINCT bug_name, package, release FROM package_notes WHERE package_kind = ''binary'' AND release <> ''''""")): @@ -792,6 +823,9 @@ % (b.source_file, b.source_line, `pkg_name`, `release`)) + if result: + return result + if self.verbose: print " remove old status" cursor.execute("DELETE FROM source_package_status") @@ -872,6 +906,25 @@ WHERE p.name = n.package AND p.release = n.release AND n.package_kind = ''binary''""") + if self.verbose: + print " source packages (from binary packages)" + cursor.execute( + """INSERT INTO source_package_status + SELECT n.id, s.rowid, + MAX(n.fixed_version IS NULL + OR b.version_id < n.fixed_version_id), + n.bug_name, s.release + FROM package_notes AS n, binary_packages AS b, + source_packages AS s + WHERE n.package_kind = ''binary'' AND b.name = n.package + AND s.name = b.source + AND s.release = b.release AND s.subrelease = b.subrelease + AND s.archive = b.archive + GROUP BY n.id, s.rowid, n.bug_name, s.release""") + # The "GROUP BY" is needed because we we might have multiple + # rows in the binary_packages table for different + # architectures. + # Calculate the release-specific bug status. if self.verbose: