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
1diff --git a/scripts/cve_lib.py b/scripts/cve_lib.py
2index 5a2b740..ace68c1 100755
3--- a/scripts/cve_lib.py
4+++ b/scripts/cve_lib.py
5@@ -1518,6 +1518,15 @@ def any_universe(map, pkg, releases, cvedata):
6 return True
7 return False
8
9+def in_universe(map, pkg, rel, cve, cvedata):
10+ if pkg in map[rel] and map[rel][pkg]['section'] == 'universe':
11+ return True
12+ else:
13+ if not cvedata:
14+ cvedata = load_cve(find_cve(cve))
15+ if pkg in cvedata['tags'] and 'universe-binary' in cvedata['tags'][pkg]:
16+ return True
17+ return False
18
19 def load_debian_dsas(filename, verbose=True):
20 dsa = None
21diff --git a/scripts/report-released-packages b/scripts/report-released-packages
22index db0f802..82d0dc0 100755
23--- a/scripts/report-released-packages
24+++ b/scripts/report-released-packages
25@@ -7,14 +7,9 @@
26 # Public License, Version 2 or later. See http://www.gnu.org/copyleft/gpl.html
27 # for details.
28
29-import datetime
30-import os
31-import re
32 import sys
33 import optparse
34 import cve_lib
35-import time
36-import json
37
38 import source_map
39
40@@ -22,15 +17,15 @@ packages = dict()
41 assignees = dict()
42 pkg_assignees = dict()
43 popularity = dict()
44-pockets = {'extended': dict(),
45+pockets = {'esm': dict(),
46 'ppa': dict(),
47 'archive': dict()}
48
49 parser = optparse.OptionParser()
50 parser.add_option("-S", "--skip-devel", help="Show only those CVEs *not* in the current devel release", action="store_true")
51 parser.add_option("-D", "--only-devel", help="Show only those CVEs in the current devel release", action="store_true")
52-parser.add_option("-e", "--only-extended", help="Show only packages with extended release status", action="store_true")
53-parser.add_option("-x", "--not-extended", help="Show only those packages without extended release status", action="store_true")
54+parser.add_option("-e", "--only-esm", help="Show only packages updated by the esm team", action="store_true")
55+parser.add_option("-x", "--not-esm", help="Show only those packages not updated by the esm team", action="store_true")
56 parser.add_option("-p", "--packages", help="Report only on the given packages", action="append", type="string")
57 parser.add_option("-P", "--pkgfamily", help="Perform pkg family renamings (use argument multiple times for 'linux' and/or 'xen')", action="append", default=[])
58 parser.add_option("-X", "--exclude", help="Ignore specified packages", action="append", type="string")
59@@ -38,7 +33,7 @@ parser.add_option("-r", "--release", help="Report only for the given releases",
60 parser.add_option("-d", "--debug", help="Report debug information while loading", action="store_true")
61 (opt, args) = parser.parse_args()
62
63-map = source_map.load()
64+srcmap = source_map.load(subprojects=cve_lib.find_subprojects())
65 releases = cve_lib.all_releases
66 for eol in cve_lib.eol_releases:
67 if eol in releases:
68@@ -65,40 +60,42 @@ for cve in sorted(cves):
69 continue
70
71 found = False
72- extended = False
73+ esm = False
74 ppa = False
75 archive = False
76+ version = 0
77 for r in releases:
78 status = table[cve]['pkgs'][pkg]
79 if status.has_key(r):
80 if status[r][0].startswith('released'):
81 #print >>sys.stderr, "%s for %s in %s (%s)" % (cve, pkg, r, table[cve][pkg][r])
82 found = True
83+ version = status[r][1]
84+ rel = r
85
86- # if has some extended release status or has esm in version
87- # then is considered extended
88- if status[r][0].startswith('released-'):
89- extended = True
90+ if '/' in r and 'trusty' not in r:
91+ rel = r.split('/')[1]
92 if 'esm' in status[r][1]:
93- extended = True
94+ esm = True
95 ppa = True
96- else:
97+ elif cve_lib.in_universe(srcmap, pkg, rel, cve, None):
98+ esm = True
99 archive = True
100
101 if not found:
102 continue
103
104- if opt.only_extended and not extended:
105+ if opt.only_esm and not esm:
106 continue
107
108- if opt.not_extended and extended:
109+ if opt.not_esm and esm:
110 continue
111
112- if extended:
113- if pockets['extended'].has_key(pkg):
114- pockets['extended'][pkg] += 1
115+ if esm:
116+ if pockets['esm'].has_key(pkg):
117+ pockets['esm'][pkg] += 1
118 else:
119- pockets['extended'][pkg] = 1
120+ pockets['esm'][pkg] = 1
121 if ppa:
122 if pockets['ppa'].has_key(pkg):
123 pockets['ppa'][pkg] += 1
124@@ -112,16 +109,20 @@ for cve in sorted(cves):
125
126
127 if packages.has_key(pkg):
128- packages[pkg] += 1
129+ packages[pkg]['cves'] += 1
130+ if version not in packages[pkg]['version']:
131+ packages[pkg]['version'].append(version)
132 else:
133- packages[pkg] = 1
134+ packages[pkg] = {}
135+ packages[pkg]['cves'] = 1
136+ packages[pkg]['version'] = [version]
137
138
139-sys.stdout.write("Updates\tPackage\n")
140+sys.stdout.write("Updates\tCVEs Fixed\tPackage\n")
141 sys.stdout.write("---------------------------------------------------------------------\n")
142
143 for pkg in sorted(packages.keys()):
144- sys.stdout.write("%s\t%s" % (str(packages[pkg]), pkg))
145+ sys.stdout.write("%s\t%s\t\t%s" % (str(len(packages[pkg]['version'])), str(packages[pkg]['cves']), pkg))
146
147 extra_info = []
148 for p in pockets.keys():

Subscribers

People subscribed via source and target branches