Merge ~litios/ubuntu-cve-tracker:oval-fixes-improvements into ubuntu-cve-tracker:master

Proposed by David Fernandez Gonzalez
Status: Merged
Merged at revision: 01d2b74924341409183a0858d3a4897f79aead06
Proposed branch: ~litios/ubuntu-cve-tracker:oval-fixes-improvements
Merge into: ubuntu-cve-tracker:master
Diff against target: 101 lines (+41/-20)
1 file modified
scripts/oval_lib.py (+41/-20)
Reviewer Review Type Date Requested Status
Eduardo Barretto Approve
Review via email: mp+459018@code.launchpad.net

Description of the change

[OVAL]

-- Fix get_pkgs function to prevent race conditions --

    Sometimes, depending on how the CVEs are loaded, function
    get_pkgs wouldn't handle the packages properly. This would
    result in different binaries between runs, making OVAL inconsistent.

-- Retrieve update pocket + extra CVE fields --

    Add a function to retrieve the pocket of a given
    package and version from the cache.

    Add Mitigation and Notes fields to the CVE.

    This is needed for the JSON per-package generation.

To post a comment you must log in.
Revision history for this message
Eduardo Barretto (ebarretto) wrote :

lgtm, thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/scripts/oval_lib.py b/scripts/oval_lib.py
2index 489200e..b30a987 100644
3--- a/scripts/oval_lib.py
4+++ b/scripts/oval_lib.py
5@@ -144,26 +144,41 @@ def generate_cve_tag(cve):
6 cve_ref += '>{0}</cve>'.format(cve['Candidate'])
7 return cve_ref
8
9+def get_real_release(cache, source_name, release) -> str:
10+ """ return the release in which the package is present.
11+ This applies for the cases where a parent release
12+ contains the package but not the requested release.
13+ """
14+
15+ if release in cache and source_name in cache[release]: return release
16+
17+ rel = release
18+ while cve_lib.release_parent(rel):
19+ rel = cve_lib.release_parent(rel)
20+ if source_name in cache[rel]:
21+ return rel
22+
23+ # if the source package does not exist in any release, return None
24+ return None
25+
26+def get_pocket(cache, source_name, version, release):
27+ """ return the pocket of a specific package version in a release """
28+ rel = get_real_release(cache, source_name, release)
29+ if not rel: return None, None
30+
31+ return rel, cache[rel][source_name][version]['pocket']
32+
33 def get_binarypkgs(cache, source_name, release):
34 """ return a list of binary packages from the source package version """
35 packages_to_ignore = ("-dev", "-doc", "-dbg", "-dbgsym", "-udeb", "-locale-")
36 binaries_map = collections.defaultdict(dict)
37-
38- if source_name not in cache[release]:
39- rel = release
40- while cve_lib.release_parent(rel):
41- rel = cve_lib.release_parent(rel)
42- r , vb = get_binarypkgs(cache, source_name, rel)
43- if r:
44- return r, vb
45-
46- # if a source package does not exist in such a release
47- # return None
48- return None, None
49
50- for source_version in cache[release][source_name]:
51+ rel = get_real_release(cache, source_name, release)
52+ if not rel: return None, None
53+
54+ for source_version in cache[rel][source_name]:
55 binaries_map.setdefault(source_version, dict())
56- for binary, bin_data in cache[release][source_name][source_version]['binaries'].items():
57+ for binary, bin_data in cache[rel][source_name][source_version]['binaries'].items():
58 # for kernel we only want linux images
59 if source_name.startswith('linux') and not binary.startswith('linux-image-'):
60 continue
61@@ -173,7 +188,7 @@ def get_binarypkgs(cache, source_name, release):
62 binaries_map[source_version].setdefault(bin_data['version'], list())
63 binaries_map[source_version][bin_data['version']].append(binary)
64
65- return release, binaries_map
66+ return rel, binaries_map
67
68 class CVEPkgRelEntry:
69 def __init__(self, pkg, release, cve, status, note) -> None:
70@@ -284,6 +299,8 @@ class CVE:
71 self.cvss = info['CVSS']
72 self.assigned_to = info['Assigned-to'] if 'Assigned-to' in info else ''
73 self.discoverd_by = info['Discovered-by'] if 'Discovered-by' in info else ''
74+ self.notes = info['Notes']
75+ self.mitigation = info['Mitigation'].strip() if 'Mitigation' in info else ''
76 self.usns = []
77 self.references = []
78 self.bugs = []
79@@ -315,13 +332,17 @@ class CVE:
80 else:
81 pkg_rel_entry = self.pkg_rel_entries[str(pkg)]
82 curr_pkg_rel_entry = self.pkg_rel_entries[str(pkg_rel[pkg.name])]
83- if curr_pkg_rel_entry.status == 'fixed':
84- priority = releases.index(pkg.rel) > releases.index(pkg_rel[pkg.name].rel) and \
85- pkg_rel_entry.fixed_version in pkg.versions_binaries
86+
87+ if curr_pkg_rel_entry.status == 'fixed' and pkg_rel_entry.status == 'fixed':
88+ """Both fixed, we keep the oldest release"""
89+ update = releases.index(pkg.rel) > releases.index(pkg_rel[pkg.name].rel)
90 else:
91- priority = releases.index(pkg.rel) < releases.index(pkg_rel[pkg.name].rel)
92+ """ If one is not fixed, we keep whichever is the newest release.
93+ A regression may happen in a child.
94+ """
95+ update = releases.index(pkg.rel) < releases.index(pkg_rel[pkg.name].rel)
96
97- if priority:
98+ if update:
99 pkg_rel[pkg.name] = pkg
100
101 for pkg in self.pkgs:

Subscribers

People subscribed via source and target branches