[Secure-testing-commits] r2062 - lib/python

Florian Weimer fw at costa.debian.org
Wed Sep 21 06:08:53 UTC 2005


Author: fw
Date: 2005-09-21 06:08:51 +0000 (Wed, 21 Sep 2005)
New Revision: 2062

Modified:
   lib/python/security_db.py
Log:
lib/python/security_db.py (DB.calculateVulnerabilities):
  Factor out testing and unstable code.
(DB._calcUnstable):
  New.  Mostly unchanged from the verison in calculateVulnerabilities.
(DB._calcTesting):
  Rewritten from scratch.  Now works on source packages.  Should be
  more reliable.


Modified: lib/python/security_db.py
===================================================================
--- lib/python/security_db.py	2005-09-21 04:03:03 UTC (rev 2061)
+++ lib/python/security_db.py	2005-09-21 06:08:51 UTC (rev 2062)
@@ -1030,184 +1030,104 @@
         for (bug_name,) in cursor.execute(
             "SELECT name FROM bugs WHERE NOT not_for_us"):
 
-            # Calculate status for unstable.  Only source package
-            # status is relevant here.
+            self._calcUnstable(c, bug_name)
+            self._calcTesting(c, bug_name)
 
-            def handle_unstable():
-                unstable_packages = []
-                for (package,) in c.execute(
-                    """SELECT DISTINCT sp.name
-                    FROM package_notes AS n,
-                    source_package_status AS st, source_packages AS sp
-                    WHERE n.bug_name = ? AND n.urgency <> 'unimportant'
-                    AND n.release = ''
-                    AND st.note = n.id AND st.vulnerable
-                    AND sp.rowid = st.package AND sp.release = 'sid'
-                    ORDER BY sp.name""",
-                    (bug_name,)):
-                    unstable_packages.append(package)
+        return result
 
-                if unstable_packages:
-                    if len(unstable_packages) == 1:
-                        pkgs = ("package %s is vulnerable"
-                                % unstable_packages[0])
-                    else:
-                        pkgs = ("packages %s are vulnerable"
-                                % ', '.join(unstable_packages))
-                    c.execute("""INSERT INTO bug_status
-                        (bug_name, release, status, reason)
-                        VALUES (?, 'unstable', 'vulnerable', ?)""",
-                              (bug_name, pkgs))
-                else:
-                    c.execute("""INSERT INTO bug_status
-                        (bug_name, release, status, reason)
-                        VALUES (?, 'unstable', 'fixed',
-                        'not known to be vulnerable')""",
-                              (bug_name,))
-            handle_unstable()
+    def _calcUnstable(self, cursor, bug_name):
+        """Update bug_status with bug_name for unstable."""
+        
+        vulnerable_packages = []
+        for (package,) in cursor.execute(
+            """SELECT DISTINCT sp.name
+            FROM package_notes AS n,
+            source_package_status AS st, source_packages AS sp
+            WHERE n.bug_name = ? AND n.urgency <> 'unimportant'
+            AND n.release = ''
+            AND st.note = n.id AND st.vulnerable
+            AND sp.rowid = st.package AND sp.release = 'sid'
+            ORDER BY sp.name""",
+            (bug_name,)):
+            vulnerable_packages.append(package)
 
-            # The algorith below roughly proceeds as follows:
-            #
-            # For each package:
-            #   Is this package in testing/unstable?  If not, exit.
-            #   
-            #   Differentiate between the following cases:
-            #     For all architectures with security support, the
-            #       package in testing is not vulnerable (fully fixed)
-            #
-            #     For all architectures with security support, the
-            #       package is not vulnerable  in testing or
-            #       testing-security, and there exists a package (on a
-            #       security support architecture) which is vulnerable
-            #       in testing (partially fixed)
-            #
-            #     There exists an architecture with security support
-            #       where the package is fixed in testing, and there
-            #       exists a non-vulnerable architecture in testing
-            #       (should not happen, partially-fixed)
-            #
-            #     Same as the preceding case, but including
-            #       test-security; this can actually happen
-            #       (partially-fixed, secure-testing is out-of-date on
-            #       some architectures)
-            #
-            #     There exists an architecture with security support
-            #       where the package is fixed in unstable, and all
-            #       packages in testing are vulnerable, and the
-            #       package is in testing (fixed in unstable)
-            #
-            #     For some supported architecture the package is in
-            #     testing, and vulnerable.  It is 
-            #
-            #     The package is not in testing on any supported
-            #     architecture,
-            #
-            # At least this is the plan.  The code below probably does
-            # something slightly different. 8-(
+        if vulnerable_packages:
+            if len(vulnerable_packages) == 1:
+                pkgs = "package %s is vulnerable" % vulnerable_packages[0]
+            else:
+                pkgs = ("packages %s are vulnerable"
+                        % ', '.join(vulnerable_packages))
+            cursor.execute("""INSERT INTO bug_status
+                (bug_name, release, status, reason)
+                VALUES (?, 'unstable', 'vulnerable', ?)""",
+                      (bug_name, pkgs))
+        else:
+            cursor.execute("""INSERT INTO bug_status
+                (bug_name, release, status, reason)
+                VALUES (?, 'unstable', 'fixed',
+                'not known to be vulnerable')""",
+                      (bug_name,))
 
-            available_archs = {}
-            vulnerable_in_other = {}
-            vulnerable_in_testing = {}
-            fixed_in_testing = {}
-            fixed_in_security = {}
+    def _calcTesting(self, cursor, bug_name):
+        """Update bug_status with bug_name for unstable."""
 
-            def record_archs_per_package(dict, pkg, archs):
-                if not dict.has_key(pkg):
-                    dict[pkg] = {}
-                for arch in archs.split(','):
-                    dict[pkg][arch] = True
-                    
-            for (pkg_name, release, subrelease, archs, vulnerable) \
-                in c.execute(
-                """SELECT DISTINCT
-                p.name, p.release, p.subrelease, p.archs, vulnerable
-                FROM binary_package_status AS s, binary_packages AS p
-                WHERE s.bug_name = ? AND p.rowid = s.package""", (bug_name,)):
-                if not binary_packages_in_testing.has_key(pkg_name):
-                    continue
+        # Note that there is at most one source package per
+        # note/release/subrelease triple, but we should check that
+        # here.  (A separate test is needed.)
 
-                record_archs_per_package(available_archs, pkg_name, archs)
+        status = {'' : {}, 'security' : {}}
+        for (package, note, subrelease, vulnerable) in cursor.execute(
+            """SELECT DISTINCT sp.name, n.id, sp.subrelease,
+            st.vulnerable
+            FROM package_notes AS n,
+            source_package_status AS st, source_packages AS sp
+            WHERE n.bug_name = ? AND n.urgency <> 'unimportant'
+            AND st.note = n.id
+            AND sp.rowid = st.package AND sp.release = 'etch'
+            AND sp.subrelease IN ('', 'security')
+            ORDER BY sp.name""",
+            (bug_name,)):
+            status[subrelease][(package, note)] = vulnerable
 
-                if release == 'etch':
-                    if vulnerable:
-                        record_archs_per_package(vulnerable_in_testing,
-                                                 pkg_name, archs)
-                    else:
-                        if subrelease == '':
-                            record_archs_per_package(fixed_in_testing,
-                                                     pkg_name, archs)
-                            record_archs_per_package(fixed_in_security,
-                                                     pkg_name, archs)
-                        elif subrelease == 'security':
-                            record_archs_per_package(fixed_in_security,
-                                                     pkg_name, archs)
-                elif vulnerable:
-                    record_archs_per_package(vulnerable_in_other,
-                                             pkg_name, archs)
+        # Check if any packages in plain testing are vulnerable, and
+        # if all of those have been fixed in the security archive.
+        fixed_in_security = True
+        pkgs = {}
+        for ((package, note), vulnerable) in status[''].items():
+            if vulnerable:
+                pkgs[package] = True
+                if status['security'].get((package, note), True):
+                    fixed_in_security = False
 
-            def record(status, reason):
-                if status <> 'vulnerable':
-                    ((has_todo,),) = c.execute(
-                        """SELECT EXISTS (SELECT * FROM bugs_notes
-                        WHERE bug_name = ? AND typ = 'TODO')""",
-                        (bug_name,))
-                    if has_todo:
-                        status = 'todo'
-                        reason = 'see notes below'
-                    
-                c.execute(
-                    """INSERT INTO bug_status
-                    (bug_name, release, status, reason)
-                    VALUES (?, 'testing', ?, ?)""",
-                    (bug_name, status, reason))
+        pkgs = pkgs.keys()
+        pkgs.sort()
+        if len(pkgs) == 0:
+            if len(status[''].keys()) == 0:
+                msg = "not known to be vulnerable"
+            else:
+                msg = "not vulnerable"
+            cursor.execute("""INSERT INTO bug_status
+            (bug_name, release, status, reason)
+            VALUES (?, 'testing', 'fixed', ?)""",
+                           (bug_name, msg))
+            return
 
-            if len(available_archs.keys()) == 0:
-                record('fixed',
-                       'package(s) neither in testing nor in unstable')
-                continue
+        if len(pkgs) == 1:
+            pkgs = "package " + pkgs[0] + " is "
+        else:
+            pkgs = "packages " + ", ".join(pkgs) + " are "
+        if fixed_in_security:
+            pkgs += "fixed in testing-security"
+            status = "partially-fixed"
+        else:
+            pkgs += "vulnerable"
+            status = "vulnerable"
 
-            totally_unfixed_packages = []
-            testing_missing_archs = {}
-            security_missing_archs = {}
-            for (pkg_name, archs) in vulnerable_in_other.items():
-                fixed_somewhere = False
-                for arch in archs.keys():
-                    if fixed_in_testing.get(pkg_name, {}).has_key(arch):
-                        fixed_somewhere = True
-                    else:
-                        testing_missing_archs[arch] = True
-                    if fixed_in_security.get(pkg_name, {}).has_key(arch):
-                        fixed_somewhere = True
-                    else:
-                        security_missing_archs[arch] = True
-                if not fixed_somewhere:
-                    totally_unfixed_packages.append(pkg_name)
-                
-            if totally_unfixed_packages:
-                totally_unfixed_packages.sort()
-                if len(totally_unfixed_packages) == 1:
-                    record('vulnerable', 'package %s is vulnerable'
-                           % totally_unfixed_packages[0])
-                else:
-                    record('vulnerable', 'packages %s are vulnerable'
-                           % ', '.join(totally_unfixed_packages))
-                continue
+        cursor.execute("""INSERT INTO bug_status
+        (bug_name, release, status, reason)
+        VALUES (?, 'testing', ?, ?)""",
+              (bug_name, status, pkgs))
 
-            if security_missing_archs.keys():
-                record('partially-fixed',
-                       'fixed via testing-security, '
-                       + 'but architectures out of date: '
-                       + ', '.join(security_missing_archs.keys()))
-                continue
-
-            if testing_missing_archs.keys():
-                record('partially-fixed', 'fixed in testing-security')
-                continue
-
-            record('fixed', 'packages are not vulnerable')
-
-        return result
-
     def getSourcePackageVersions(self, cursor, pkg):
         """A generator which returns tuples (RELEASE-LIST, VERSION),
         the available versions of the source package pkg."""




More information about the Secure-testing-commits mailing list