Merge ~ebarretto/ubuntu-cve-tracker:report-released-packages into ubuntu-cve-tracker:master

Proposed by Eduardo Barretto
Status: Merged
Merged at revision: fb2855a30201e6651f31adee23cd9a08c0f554a4
Proposed branch: ~ebarretto/ubuntu-cve-tracker:report-released-packages
Merge into: ubuntu-cve-tracker:master
Diff against target: 148 lines (+36/-26)
2 files modified
scripts/cve_lib.py (+9/-0)
scripts/report-released-packages (+27/-26)
Reviewer Review Type Date Requested Status
Emilia Torino Approve
Review via email: mp+401550@code.launchpad.net

Description of the change

NOTE: This PR SHOULD NOT be merged until we get to work on the metric scripts that use this report.

This PR is intended to prepare for upcoming releases and enhance the report-released-packages script. The PR contain 3 commits:

1. Add in_universe function to cve_lib:
   Even though we have is_universe, it doesn't actually check if srcpkg or binary in universe. So, in order to not break other scripts, adding a new function to check if a srcpkg or binary is in universe was needed.

2. Adapt report-released-packages to better track archive updates:
   With 16.04 esm near launch, released-esm and experimental directory will go away, so we needed a better way to track archive updates.

3. Alter report-released-packages to show number of updates per package and number of cves:
   The current report-released-packages show the number of updates, but that is actually the number of CVEs fixed. So I've extended to also get the number of updates per package.

To post a comment you must log in.
Revision history for this message
Emilia Torino (emitorino) wrote :

Changes look good but is difficult to review the code without understanding how is exercised (e.g. I am not familiar with the content of map[rel][pkg]['section'] to understand if that's correct) or the impact it could have on whoever is consuming them (e.g. changing packages[pkg] = 1 to packages[pkg] = {}).

review: Approve
Revision history for this message
Steve Beattie (sbeattie) wrote :

Hi Eduardo,

I don't know much about this script, does it need to run on people.c.c or elsewhere?

Revision history for this message
Eduardo Barretto (ebarretto) wrote :

> Hi Eduardo,
>
> I don't know much about this script, does it need to run on people.c.c or
> elsewhere?

Yes, I believe this runs in keule in a cron job and is what the kpi scripts uses to get some of the metrics on esm.

Revision history for this message
Steve Beattie (sbeattie) wrote :

On Wed, Apr 21, 2021 at 02:46:21PM -0000, Eduardo Barretto wrote:
> 1. Add in_universe function to cve_lib:
> Even though we have is_universe, it doesn't actually check if srcpkg or binary in universe. So, in order to not break other scripts, adding a new function to check if a srcpkg or binary is in universe was needed.

I'm not sure what you mean here. is_universe() ends up calling
is_supported(), which at the end (after doing a bunch of work around
overlays) does:

    # Allow for a tagged override to declare a pkg (from the perspective of
    # a given CVE item) to be unsupported.
    if cvedata and pkg in cvedata['tags'] and \
       ('universe-binary' in cvedata['tags'][pkg] or
        'not-ue' in cvedata['tags'][pkg]):
        return False
    # Look for component or if we have a partially supported release, and if
    # partially supported only support those packages that are supported
    if pkg in map[rel] and \
       (map[rel][pkg]['section'] == 'main' or
        map[rel][pkg]['section'] == 'restricted') and \
       (len(supported_pkgs[rel]) == 0 or pkg in supported_pkgs[rel]):
        return True
    return False

which looks for the 'universe-binary' tag[0] in any of the attached cves.
Else, it looks to see whether the source packages is in 'main'
or 'restricted' (the two supported components) for that release.
Alternatively, it looks in the esm-infra lists for that package (I
believe) to see if it's supported there. For non-ESM-infra releases,
things that aren't in 'main' or 'restricted' will be in either
'universe' or 'multiverse' which is really what our colloquial usage
of the term 'universe' covers.

[0] or 'not-ue', which looks to have only affected 2017 kernels, 'ue' here
    I believe means 'ubuntu-engineering' and that those kernels were
    supported by a team outside of ubuntu engineering.

--
Steve Beattie
<email address hidden>

Revision history for this message
Eduardo Barretto (ebarretto) wrote :

> On Wed, Apr 21, 2021 at 02:46:21PM -0000, Eduardo Barretto wrote:
> > 1. Add in_universe function to cve_lib:
> > Even though we have is_universe, it doesn't actually check if srcpkg or
> binary in universe. So, in order to not break other scripts, adding a new
> function to check if a srcpkg or binary is in universe was needed.
>
> I'm not sure what you mean here. is_universe() ends up calling
> is_supported(), which at the end (after doing a bunch of work around
> overlays) does:
>
> # Allow for a tagged override to declare a pkg (from the perspective of
> # a given CVE item) to be unsupported.
> if cvedata and pkg in cvedata['tags'] and \
> ('universe-binary' in cvedata['tags'][pkg] or
> 'not-ue' in cvedata['tags'][pkg]):
> return False
> # Look for component or if we have a partially supported release, and if
> # partially supported only support those packages that are supported
> if pkg in map[rel] and \
> (map[rel][pkg]['section'] == 'main' or
> map[rel][pkg]['section'] == 'restricted') and \
> (len(supported_pkgs[rel]) == 0 or pkg in supported_pkgs[rel]):
> return True
> return False
>
> which looks for the 'universe-binary' tag[0] in any of the attached cves.
> Else, it looks to see whether the source packages is in 'main'
> or 'restricted' (the two supported components) for that release.
> Alternatively, it looks in the esm-infra lists for that package (I
> believe) to see if it's supported there. For non-ESM-infra releases,

The current problem is exactly on the esm-infra lists of packages, with 16.04 ESM
coming up, we don't have a list of packages anymore as the scope changed:
https://wiki.ubuntu.com/SecurityTeam/ESM/16.04#Maintained_Packages

That also means that source_map right now won't load esm-infra/xenial (e.g.
check source_map.load() and source_map.load_ppa(), it is based in the esm-infra
list of packages). Also, source_map won't load xenial, as it will be listed in
cve_lib.eol_releases.

In order to make is_supported work with upcoming esm, we would need to address
those changes.

Also, for 14.04 ESM we do have a list of universe packages, pretty much like the
esm-infra list, so is_supported is returning True for those universe packages
which would then make is_universe return False. This needs to be investigated
further, as I believe some tools expect to see those 14.04 universe packages as
"supported".

That's why I created this new in_universe function.

We can certainly have a meeting and try to come up with a better solution.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/scripts/cve_lib.py b/scripts/cve_lib.py
index 5a2b740..ace68c1 100755
--- a/scripts/cve_lib.py
+++ b/scripts/cve_lib.py
@@ -1518,6 +1518,15 @@ def any_universe(map, pkg, releases, cvedata):
1518 return True1518 return True
1519 return False1519 return False
15201520
1521def in_universe(map, pkg, rel, cve, cvedata):
1522 if pkg in map[rel] and map[rel][pkg]['section'] == 'universe':
1523 return True
1524 else:
1525 if not cvedata:
1526 cvedata = load_cve(find_cve(cve))
1527 if pkg in cvedata['tags'] and 'universe-binary' in cvedata['tags'][pkg]:
1528 return True
1529 return False
15211530
1522def load_debian_dsas(filename, verbose=True):1531def load_debian_dsas(filename, verbose=True):
1523 dsa = None1532 dsa = None
diff --git a/scripts/report-released-packages b/scripts/report-released-packages
index db0f802..82d0dc0 100755
--- a/scripts/report-released-packages
+++ b/scripts/report-released-packages
@@ -7,14 +7,9 @@
7# Public License, Version 2 or later. See http://www.gnu.org/copyleft/gpl.html7# Public License, Version 2 or later. See http://www.gnu.org/copyleft/gpl.html
8# for details.8# for details.
99
10import datetime
11import os
12import re
13import sys10import sys
14import optparse11import optparse
15import cve_lib12import cve_lib
16import time
17import json
1813
19import source_map14import source_map
2015
@@ -22,15 +17,15 @@ packages = dict()
22assignees = dict()17assignees = dict()
23pkg_assignees = dict()18pkg_assignees = dict()
24popularity = dict()19popularity = dict()
25pockets = {'extended': dict(),20pockets = {'esm': dict(),
26 'ppa': dict(),21 'ppa': dict(),
27 'archive': dict()}22 'archive': dict()}
2823
29parser = optparse.OptionParser()24parser = optparse.OptionParser()
30parser.add_option("-S", "--skip-devel", help="Show only those CVEs *not* in the current devel release", action="store_true")25parser.add_option("-S", "--skip-devel", help="Show only those CVEs *not* in the current devel release", action="store_true")
31parser.add_option("-D", "--only-devel", help="Show only those CVEs in the current devel release", action="store_true")26parser.add_option("-D", "--only-devel", help="Show only those CVEs in the current devel release", action="store_true")
32parser.add_option("-e", "--only-extended", help="Show only packages with extended release status", action="store_true")27parser.add_option("-e", "--only-esm", help="Show only packages updated by the esm team", action="store_true")
33parser.add_option("-x", "--not-extended", help="Show only those packages without extended release status", action="store_true")28parser.add_option("-x", "--not-esm", help="Show only those packages not updated by the esm team", action="store_true")
34parser.add_option("-p", "--packages", help="Report only on the given packages", action="append", type="string")29parser.add_option("-p", "--packages", help="Report only on the given packages", action="append", type="string")
35parser.add_option("-P", "--pkgfamily", help="Perform pkg family renamings (use argument multiple times for 'linux' and/or 'xen')", action="append", default=[])30parser.add_option("-P", "--pkgfamily", help="Perform pkg family renamings (use argument multiple times for 'linux' and/or 'xen')", action="append", default=[])
36parser.add_option("-X", "--exclude", help="Ignore specified packages", action="append", type="string")31parser.add_option("-X", "--exclude", help="Ignore specified packages", action="append", type="string")
@@ -38,7 +33,7 @@ parser.add_option("-r", "--release", help="Report only for the given releases",
38parser.add_option("-d", "--debug", help="Report debug information while loading", action="store_true")33parser.add_option("-d", "--debug", help="Report debug information while loading", action="store_true")
39(opt, args) = parser.parse_args()34(opt, args) = parser.parse_args()
4035
41map = source_map.load()36srcmap = source_map.load(subprojects=cve_lib.find_subprojects())
42releases = cve_lib.all_releases37releases = cve_lib.all_releases
43for eol in cve_lib.eol_releases:38for eol in cve_lib.eol_releases:
44 if eol in releases:39 if eol in releases:
@@ -65,40 +60,42 @@ for cve in sorted(cves):
65 continue60 continue
6661
67 found = False62 found = False
68 extended = False63 esm = False
69 ppa = False64 ppa = False
70 archive = False65 archive = False
66 version = 0
71 for r in releases:67 for r in releases:
72 status = table[cve]['pkgs'][pkg]68 status = table[cve]['pkgs'][pkg]
73 if status.has_key(r):69 if status.has_key(r):
74 if status[r][0].startswith('released'):70 if status[r][0].startswith('released'):
75 #print >>sys.stderr, "%s for %s in %s (%s)" % (cve, pkg, r, table[cve][pkg][r])71 #print >>sys.stderr, "%s for %s in %s (%s)" % (cve, pkg, r, table[cve][pkg][r])
76 found = True72 found = True
73 version = status[r][1]
74 rel = r
7775
78 # if has some extended release status or has esm in version76 if '/' in r and 'trusty' not in r:
79 # then is considered extended77 rel = r.split('/')[1]
80 if status[r][0].startswith('released-'):
81 extended = True
82 if 'esm' in status[r][1]:78 if 'esm' in status[r][1]:
83 extended = True79 esm = True
84 ppa = True80 ppa = True
85 else:81 elif cve_lib.in_universe(srcmap, pkg, rel, cve, None):
82 esm = True
86 archive = True83 archive = True
8784
88 if not found:85 if not found:
89 continue86 continue
9087
91 if opt.only_extended and not extended:88 if opt.only_esm and not esm:
92 continue89 continue
9390
94 if opt.not_extended and extended:91 if opt.not_esm and esm:
95 continue92 continue
9693
97 if extended:94 if esm:
98 if pockets['extended'].has_key(pkg):95 if pockets['esm'].has_key(pkg):
99 pockets['extended'][pkg] += 196 pockets['esm'][pkg] += 1
100 else:97 else:
101 pockets['extended'][pkg] = 198 pockets['esm'][pkg] = 1
102 if ppa:99 if ppa:
103 if pockets['ppa'].has_key(pkg):100 if pockets['ppa'].has_key(pkg):
104 pockets['ppa'][pkg] += 1101 pockets['ppa'][pkg] += 1
@@ -112,16 +109,20 @@ for cve in sorted(cves):
112109
113110
114 if packages.has_key(pkg):111 if packages.has_key(pkg):
115 packages[pkg] += 1112 packages[pkg]['cves'] += 1
113 if version not in packages[pkg]['version']:
114 packages[pkg]['version'].append(version)
116 else:115 else:
117 packages[pkg] = 1116 packages[pkg] = {}
117 packages[pkg]['cves'] = 1
118 packages[pkg]['version'] = [version]
118119
119120
120sys.stdout.write("Updates\tPackage\n")121sys.stdout.write("Updates\tCVEs Fixed\tPackage\n")
121sys.stdout.write("---------------------------------------------------------------------\n")122sys.stdout.write("---------------------------------------------------------------------\n")
122123
123for pkg in sorted(packages.keys()):124for pkg in sorted(packages.keys()):
124 sys.stdout.write("%s\t%s" % (str(packages[pkg]), pkg))125 sys.stdout.write("%s\t%s\t\t%s" % (str(len(packages[pkg]['version'])), str(packages[pkg]['cves']), pkg))
125126
126 extra_info = []127 extra_info = []
127 for p in pockets.keys():128 for p in pockets.keys():

Subscribers

People subscribed via source and target branches