def fixed_map(priority=None): fixed = [] for usn in sorted(db.keys()): if not db[usn].has_key('cves'): continue for cve in db[usn]['cves']: if not cve.startswith('CVE-'): continue if not release or db[usn]['releases'].has_key(release): # Load CVE if it isn't already cached if not info.has_key(cve): try: info.setdefault( cve, cve_lib.load_cve(cve_lib.find_cve(cve))) except Exception, e: print >> sys.stderr, "Skipping %s: %s" % (cve, str(e)) continue # Skip those without PublicDates for the moment if info[cve]['PublicDate'].strip() == "": print >> sys.stderr, "%s: empty PublicDate" % (cve) continue # Check priority # from the all releases or a specific release, find the # mapping of CVE priority based on the package that was # fixed in the USN. In the case of multiple match, first # most specific wins. max_specificity = -1 cve_priority = info[cve]['Priority'] tried = [] for rel in db[usn]['releases']: if not release or release == rel: if db[usn]['releases'][rel].has_key('sources'): for pkg in db[usn]['releases'][rel]['sources']: specificity, specific_priority = cve_lib.contextual_priority( info[cve], pkg, rel) if specificity > max_specificity: cve_priority = specific_priority max_specificity = specificity if not priority or cve_priority == priority: oldest = None if release: oldest = cve_lib.release_stamps[release] fixed.append([ cve, cve_lib.cve_age(cve, info[cve]['PublicDate'], db[usn]['timestamp'], oldest), usn, cve_priority ])
def post_single_cve(cve_filename): # Upload active and ignored (in Ubuntu) cve_data = cve_lib.load_cve(cve_filename) references = cve_data["References"].split("\n") if references[0] == "": references.pop(0) cvss3 = None if len(cve_data["CVSS"]) > 0: if "3." in cve_data["CVSS"][0][1]: # Use CVSS3 c = CVSS3(cve_data["CVSS"][0][1]) cvss3 = c.scores()[0] packages = [] tags = {} patches = {} for pkg in cve_data["pkgs"]: statuses = [] cve_releases = cve_data["pkgs"][pkg].keys() cve_releases = [rel for rel in cve_releases if rel in cve_lib.releases] tags[pkg] = get_tags(cve_data, pkg) patches[pkg] = get_patches(cve_data, pkg) for [raw_codename, value] in cve_data["pkgs"][pkg].items(): codename = get_codename(raw_codename, cve_releases) if codename is None: continue if codename in cve_lib.releases + ["upstream"]: statuses.append( { "release_codename": codename, "status": value[0], "description": value[1], } ) package = { "name": pkg, "source": f"https://launchpad.net/ubuntu/+source/{pkg}", "ubuntu": f"https://packages.ubuntu.com/search?suite=all§ion=all&arch=any&searchon=sourcenames&keywords={pkg}", "debian": f"https://tracker.debian.org/pkg/{pkg}", "statuses": statuses, } packages.append(package) status = "active" if "** REJECT **" in cve_data["Description"]: status = "rejected" notes = [] for [author, note] in cve_data["Notes"]: notes.append({"author": author, "note": note}) priority = cve_data["Priority"] if priority == "untriaged": priority = "unknown" cve = { "id": cve_data["Candidate"], "description": cve_data["Description"], "ubuntu_description": cve_data["Ubuntu-Description"], "notes": notes, "priority": priority, "cvss3": cvss3, # CVSS vector to convert into Base score "references": references, "bugs": cve_data["Bugs"].strip().split(), "packages": packages, "status": status, "tags": tags, "patches": patches, } if cve_data["PublicDate"] != "unknown": cve["published"] = cve_data["PublicDate"] return cve
def fixed_map(priority=None): fixed = dict() for usn in sorted(db.keys()): if 'cves' not in db[usn]: continue for cve in db[usn]['cves']: if not cve.startswith('CVE-'): continue if not release or release in db[usn]['releases']: # Load CVE if it isn't already cached if cve not in info: try: info.setdefault( cve, cve_lib.load_cve(cve_lib.find_cve(cve))) except Exception as e: print("Skipping %s: %s" % (cve, str(e)), file=sys.stderr) continue # Skip those without PublicDates for the moment if info[cve]['PublicDate'].strip() == "": print("%s: empty PublicDate" % (cve), file=sys.stderr) continue # Check priority # from the all releases or a specific release, find the # mapping of CVE priority based on the package that was # fixed in the USN. In the case of multiple match, first # most specific wins. for rel in db[usn]['releases']: if not release or release == rel: if 'sources' in db[usn]['releases'][rel]: for pkg in db[usn]['releases'][rel]['sources']: # For now, hard-code list of source packages # we're ignoring. This will need to be dealt # with in a better way once we have a fuller # understanding of the ramifications of having # multiple source packages for the kernel. if pkg in [ 'linux-mvl-dove', 'linux-fsl-imx51', 'linux-ec2', 'linux-qcm-msm', 'linux-ti-omap', 'linux-armadaxp' ] and 'linux' in db[usn]['releases'][rel][ 'sources']: continue # Skip updates duplicated in firefox if pkg in ['xulrunner-1.9.2', 'thunderbird' ] and 'firefox' in db[usn][ 'releases'][rel]['sources']: continue specificity, cve_priority = cve_lib.contextual_priority( info[cve], pkg, rel) if not priority or cve_priority == priority: report_pkg = pkg if pkg in cve_lib.pkg_alternates: report_pkg = cve_lib.pkg_alternates[ pkg] fixed.setdefault(report_pkg, dict()) fixed[report_pkg].setdefault( cve_priority, set()) fixed[report_pkg][cve_priority].add(cve) return fixed
months[when]['total'] += count else: if opt.target == 'cve': if not db[usn].has_key('cves'): continue for cve in db[usn]['cves']: # Skip non-CVEs: if not cve.startswith('CVE'): continue if opt.release and opt.release not in db[usn]['releases']: continue if not cves.has_key(cve): try: cves.setdefault( cve, cve_lib.load_cve(cve_lib.find_cve(cve))) except Exception, e: print >> sys.stderr, "Skipping %s: %s" % (cve, str(e)) continue months[when]['total'] += 1 months[when][cves[cve]['Priority']] += 1 else: for rel in db[usn]['releases']: if opt.release and rel != opt.release: continue if opt.target == 'src': if not db[usn]['releases'][rel].has_key('sources'): # Assume that the early USNs updated 1 srcpkg per release months[when]['total'] += 1 #pp.pprint(db[usn])
rc = 0 empty = set() for cve in opt.cve + args: if cve.endswith(','): cve = cve[:-1] # CVE references can be bug numbers like https://launchpad.net/bugs/XXXXXX. # These obviously don't exist on the filesystem, so silently ignore URLs # but report other malformed CVEs if not cve.startswith('CVE'): if not cve.startswith('http'): print("Skipping invalid CVE identifier '%s'" % cve, file=sys.stderr) continue filename = get_filename(cve, use_embargoed=(opt.embargoed == True)) if os.path.exists(filename): cves[cve] = cve_lib.load_cve(filename) chunks = cves[cve] desc = chunks['Ubuntu-Description'].strip() if len(desc) == 0: rc = 1 disc = chunks.get('Discovered-by', '').strip() if len(disc) > 0: disc += ':' desc = 'XXX-FIXME-XXX %s[%s]' % (disc, chunks['Description'].strip()) desc = desc.replace('\n', ' ').replace(' ', ' ').replace(' ', ' ') if len(desc) == 0: rc = 1 desc = "XXX-FIXME-%s-HAS-EMPTY-DESCRIPTION-XXX" % (cve) else: rc = 1
def htmlize_package(outfd, pkg, cvefiles, commit=None): html_header('%s CVEs in Ubuntu' % pkg, 'Ubuntu Package CVE Entry for %s' % pkg, outfd) print('<h2 class="card-header">Package: %s</h2>' % (quote(pkg)), file=outfd) print('<div class="card-body text-left">', file=outfd) notes = set() # Loading the source map is expensive, which is unfortunate. We will # do it only for pkg html output, since the generate-pkg-makefile script # is already trying to minimize how much we run this function. global map if not map: import source_map map = source_map.load() # Merged package reports (linux-source-2.6.15 should appear in # linux) only work when a package (linux) does not exist in a given # release (dapper) but the replacement does (linux-source-2.6.15). # So, figure out which pkg should be used for lookups in each in release: pkgname = dict() for rel in releases: rel_orig = rel if rel == cve_lib.devel_release: rel = 'devel' pkgname[rel_orig] = pkg if pkg not in map[rel_orig] and pkg in cve_lib.pkg_aliases: # Aliases: 'linux-source-2.6.15' should appear in 'linux' output for alias in cve_lib.pkg_aliases[pkg]: if alias in map[rel_orig]: #print >>sys.stderr, "\tfound alias '%s' for '%s'" % (alias, pkg) pkgname[rel_orig] = alias notes.add( 'CVEs from <a href="%s.html">%s</a> in %s have been merged into this report' % (quote(alias), escape(alias), escape(rel_orig))) break # For a given source package, if it is supported for a release, but # there is a CVE that is marked as affecting a universe binary only, # we need to mark it as "community supported". Start by building up # a map of supportability per-release for the source package. starred = False src_supported = dict() headings = [] entire_release_starred = set() for rel in releases: heading = rel if '/' in rel: (base, ppa) = rel.split('/') heading = "%s/" % (base) if ppa == "ubuntu-core": heading += "Core" elif ppa == "stable-phone-overlay": heading += "Touch" else: # abbreviate the ppa name if we don't know about it for i in ppa.split('-'): heading += i[0] src_supported[rel] = False if pkgname[rel] and pkgname[rel] in map[rel]: src_supported[rel] = cve_lib.is_supported(map, pkgname[rel], rel) if not src_supported[rel]: starred = True entire_release_starred.add(rel) heading += "*" headings.append(heading) if len(cvefiles) == 0: print( '<div class="item text-center"><h3>Status</h3> <div class="value">No known vulnerable public CVEs</div></div>', file=outfd) else: cvefiles.sort(cve_lib.cve_sort) print( '<div class="item text-center"><h3>Status</h3> <div class="value">%d known public CVEs</div></div>' % (len(cvefiles)), file=outfd) if len(notes) > 0: print('<div class="item text-center"><h3>Notes</h3>', file=outfd) for note in sorted(notes): print('<div class="value">%s</div>' % (note), file=outfd) print('</div>', file=outfd) print('<h3 class="text-center">CVEs</h3>', file=outfd) print( '<table id="cves" class="table table-bordered table-hover text-center">' + htmlTableHeader(headings), file=outfd) for cvefile in cvefiles: data = cve_lib.load_cve(cvefile) # Sort out priority priority = cve_lib.contextual_priority(data)[1] print('<tr class="%s">' % (quote(priority)), end=' ', file=outfd) # fields... # 'pkgs' -> dict( pkg -> dict( release -> (state, notes) ) ) cve = data['Candidate'] #print >>sys.stderr, 'cve: %s' % (cve) print('<td class="cve"><a href="../%s">%s</a></td>' % (quote(cve), escape(cve)), end=' ', file=outfd) for rel in releases: rel_orig = rel if rel == cve_lib.devel_release: rel = 'devel' report_pkg = pkgname[rel_orig] # Sort out priority override priority_override = cve_lib.contextual_priority(data, pkg=report_pkg, rel=rel)[1] #print >>sys.stderr, '\tlooking for %s' % (report_pkg) if report_pkg in data['pkgs'] and rel in data['pkgs'][ report_pkg]: pkgstatus = data['pkgs'][report_pkg][rel][0] pkgnotes = data['pkgs'][report_pkg][rel][1] pkgclass = pkgstatus #print >>sys.stderr, '\t\tstatus for %s is %s' % (report_pkg, pkgclass) if pkgclass == 'DNE': pkgstatus = "--" if pkgstatus == 'pending' and pkgnotes != '': pkgclass = 'pendingversion' priority_class = "" priority_start = "" priority_end = "" if priority_override != priority: priority_class = " override" priority_start = '<div class="%s">' % ( quote(priority_override)) priority_end = '</div>' # Sort out supportability override if pkgstatus not in ["--", "not-affected"] and \ src_supported[rel_orig] and \ not cve_lib.is_supported(map, report_pkg, rel_orig, data): starred = True pkgstatus += "*" print('<td class="%s%s">%s%s%s</td>' % (quote(pkgclass), priority_class, priority_start, escape(pkgstatus), priority_end), end=' ', file=outfd) else: print('<td class="DNE">--</td>', end=' ', file=outfd) print('</tr>', file=outfd) print('</table>', file=outfd) if starred: print('<p class="note text-right">* community supported</p>', file=outfd) html_footer(outfd, commit)
def htmlize_cve(cvefile, outfd, commit=None): data = cve_lib.load_cve(cvefile) #import pprint #pp = pprint.PrettyPrinter(indent=4) #pp.pprint(data) cve = data['Candidate'] html_header('%s in Ubuntu' % cve, 'Ubuntu %s Entry' % cve, outfd) # CVE cross links heading = quote(cve) print('<h3 class="card-header">%s</h3>' % (heading), file=outfd) print('<div class="card-body text-left">', file=outfd) # Handle "free-form" text for field in [ 'Priority', 'Description', 'Ubuntu-Description', 'References', 'Bugs', 'Mitigation', 'Assigned-to' ]: if field not in data: continue text = data[field].strip() if len(text) == 0: continue escaped_body = htmlize_field(field, text) if field == "Priority": # CVEs that are marked not-for-us should not display priority. if text == 'not-for-us': continue escaped_body = '<a href="../priority.html">' + escaped_body.capitalize( ) + '</a>' print( '<div class="item"><div class="field">%s</div> <div>%s</div></div>' % (escape(field), escaped_body), file=outfd) # Notes are special if 'Notes' in data: print('<div class="item"><div class="field">Notes</div><div>', file=outfd) print('<table class="table table-responsive">', file=outfd) for (user, note) in data['Notes']: print( ( '<tr><td class="user">%s</td><td class="note">%s</td></tr>' % # preserve line breaks (escape(user), escape(note).replace("\n", "<br />\n"))), file=outfd) print('</table>', file=outfd) print('</div></div>', file=outfd) # Handle package logic for pkg in sorted(data['pkgs']): print('<div class="pkg">', file=outfd) if 'product' in data['pkgs'][pkg].keys(): print('<div class="field">Product</div><div class="value">Source tree: ' + \ '<a href="%s">%s</a>' % (escape(cve_lib.supported_products[pkg][0]), escape(cve_lib.supported_products[pkg][0])) + \ '</div>', file=outfd) elif 'snap' in data['pkgs'][pkg].keys(): print('<div class="field">Snap</div><div class="value">Store: ' + \ '<a href="https://snapcraft.io/%s">%s</a>' % (escape(pkg), escape(pkg)) + \ '</div>', file=outfd) else: print('<div class="field">Package</div><div>Source: ' + \ '<a href="../pkg/%s.html">%s</a> ' % (quote(pkg), escape(pkg)) + \ '(' + \ '<a href="https://launchpad.net/distros/ubuntu/+source/%s">LP</a> ' % (quote(pkg)) + \ '<a href="https://packages.ubuntu.com/search?suite=all&section=all&arch=any&searchon=sourcenames&keywords=%s">Ubuntu</a> ' % (quote(pkg)) + \ '<a href="https://tracker.debian.org/%s">Debian</a>' % (quote(pkg)) + \ ')</div>', file=outfd) if 'Priority_%s' % pkg in data: # per package priority override exists priority_override = escape(data['Priority_%s' % pkg]).capitalize() #value_class = lookup_priority_class(priority_override) print('<div>Priority: %s</div>' % (priority_override), file=outfd) #print('<div class="item"><div class="value">Priority:</div> <div class="%s">%s</div></div>' % (value_class, priority_override), file=outfd) print('<table class="table table-responsive">', file=outfd) # figure out what the development release was based on the releases # in the CVE # Bah, this should just be a separate function to determine the # devel release given a list of releases. cve_devel_release = cve_lib.devel_release cve_releases = data['pkgs'][pkg].keys() for skip_release in ['upstream', 'devel', 'product', 'snap']: if skip_release in cve_releases: cve_releases.remove(skip_release) if len(cve_releases) > 0: cve_releases = cve_lib.release_sort(cve_releases) try: index = all_releases.index(cve_releases[-1]) + 1 if index < len(all_releases) and all_releases[index]: cve_devel_release = all_releases[index] except: pass if cve_devel_release not in releases: cve_devel_release = 'EOL ' + cve_devel_release release_list = ['upstream', 'product', 'snap'] + releases for release in release_list: relname = release if relname == cve_devel_release: release = 'devel' if release not in data['pkgs'][pkg]: continue status = data['pkgs'][pkg][release][0] notes = data['pkgs'][pkg][release][1] if relname in cve_lib.release_names: release_title = cve_lib.release_names[relname] else: release_title = relname.capitalize() if relname == 'product' or relname == 'snap': release_title = quote(pkg) name = '%s' % (escape(release_title)) if status != 'DNE' and relname != 'upstream' and relname != 'product' and relname != 'snap' and '/' not in relname: name = '<a href="https://launchpad.net/ubuntu/%s/+source/%s">%s</a>' % ( quote(relname), quote(pkg), escape(release_title)) status_class = "default" if status in ['needed', 'active', 'deferred']: status_class = "vuln" elif status in cve_lib.status_closed: status_class = "safe" elif status == 'pending': status_class = "pending" print('<tr><td>%s:</td><td><span class="%s">%s</span>' % (name, status_class, status), file=outfd) if len(notes): print('(%s)' % (escape(notes)), file=outfd) print('</td></tr>', file=outfd) print('</table>', file=outfd) patches = 'Patches_%s' % (pkg) if patches in data: entries = data[patches] if entries != "": print('<div class="patches">Patches:</div>', file=outfd) print('<table class="table table-responsive patches">', file=outfd) for patch in entries.split('\n'): if not ':' in patch: continue source, url = patch.split(':', 1) url = url.strip() if source == "break-fix" and " " in url: introduced, fixed = url.split(' ', 1) if introduced == '-': # First commit to Linux git tree introduced = '1da177e4c3f41524e886b7f1b8a0c1fc7321cac2' print( '<tr><td>Introduced by <pre><a href="https://git.kernel.org/linus/%s">%s</a></pre></td><td>Fixed by <pre><a href="https://git.kernel.org/linus/%s">%s</a></pre></td></tr>' % (introduced, introduced, fixed, fixed), file=outfd) else: if re.match('^(ftp|http)[s]?://', url): print( '<tr><td>%s:</td><td><a href="%s">%s</a></td></tr>' % (escape(source).capitalize(), url.replace('"', '%22'), escape(url)), file=outfd) else: print('<tr><td>%s:</td><td>%s</td></tr>' % (escape(source).capitalize(), escape(url)), file=outfd) if entries != "": print('</table>', file=outfd) # tags urlregex = re.compile(r"(http[^\s]+)") if pkg in data['tags']: tags = data['tags'][pkg] for tag in tags: # linkify any url in description description = cve_lib.valid_tags[tag] description = re.sub(urlregex, '<a href="\\1">\\1</a>', description) print('<div>%s</div>' % (description), file=outfd) print('</div>', file=outfd) print('<div class="item">', file=outfd) print('<div class="field">More Information</div>', file=outfd) print( '<ul class="links"><li><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=%s">Mitre</a></li><li><a href="https://nvd.nist.gov/nvd.cfm?cvename=%s">NVD</a></li><li><a href="https://launchpad.net/bugs/cve/%s">Launchpad</a></li><li><a href="https://security-tracker.debian.org/tracker/%s">Debian</a></li></ul>' % (quote(cve), quote(cve), quote(cve), quote(cve)), file=outfd) print('</div>', file=outfd) html_footer(outfd, commit)
if sync_to_bug_phase1(bug, tasks, data): touched = True if sync_from_bug_phase2(bug, tasks, data): touched = True if sync_to_bug_phase3(bug, tasks, data): touched = True return touched if __name__ == '__main__': # Find only open kernel CVEs info = dict() for filename in cves: cve = os.path.basename(filename) data = cve_lib.load_cve(filename) for src in cve_lib.kernel_srcs: if src not in data['pkgs']: continue found = False for rel in data['pkgs'][src]: if rel == "upstream": continue if not data['pkgs'][src][rel][0] in cve_lib.status_closed: # print "Want %s (%s: %s)" % (cve, src, data['pkgs'][src][rel][0]) info.setdefault(cve, data) found = True break if found: break
def post_single_cve(cve_filename): # Upload active and ignored (in Ubuntu) cve_data = cve_lib.load_cve(cve_filename) references = cve_data["References"].split("\n") if references[0] == "": references.pop(0) cvss3 = None if len(cve_data["CVSS"]) > 0: if "3." in cve_data["CVSS"][0][1]: # Use CVSS3 c = CVSS3(cve_data["CVSS"][0][1]) cvss3 = c.scores()[0] packages = [] for pkg in cve_data["pkgs"]: statuses = [] for [key, value] in cve_data["pkgs"][pkg].items(): codename_parts = key.split("/") codename = codename_parts[0] if codename == "devel": codename = "focal" if codename in cve_lib.releases + ["upstream"]: statuses.append({ "release_codename": codename, "status": value[0], "description": value[1], }) package = { "name": pkg, "source": f"https://people.canonical.com/~ubuntu-security/cve/pkg/{key}.html", "ubuntu": f"https://packages.ubuntu.com/search?suite=all§ion=all&arch=any&searchon=sourcenames&keywords={key}", "debian": f"https://tracker.debian.org/pkg/{key}", "statuses": statuses, } packages.append(package) status = "active" if "** REJECT **" in cve_data["Description"]: status = "rejected" notes = [] for [author, note] in cve_data["Notes"]: notes.append({"author": author, "note": note}) priority = cve_data["Priority"] if priority == "untriaged": priority = "unknown" cve = { "id": cve_data["Candidate"], "published": cve_data["PublicDate"], "description": cve_data["Description"], "ubuntu_description": cve_data["Ubuntu-Description"], "notes": notes, "priority": priority, "cvss3": cvss3, # CVSS vector to convert into Base score "references": references, "bugs": cve_data["Bugs"].strip().split(), "packages": packages, "status": status, } return cve
report += ' (%s)' % (", ".join([ "%s %s" % (x, db[usn]['releases'][release]['sources'][x]['version']) for x in db[usn]['releases'][release]['sources'] ])) cves = [] for cve in sorted(db[usn]['cves']): info = None if cve.startswith("CVE-") and usn in usns: unique_cves.add(cve) if report_priorities or opt.description: # Skip non-CVEs and missing CVEs. try: filename = cve_lib.find_cve(cve) info = cve_lib.load_cve(filename) except: continue if report_priorities: specificity, cve_priority = cve_lib.contextual_priority( info, src, release) # Skip CVEs that we aren't interested in. if not cve_priority in report_priorities: continue cve = "%s (%s)" % (cve, cve_priority) if opt.description: text = info.get('Ubuntu-Description', info['Description']).strip() # Skip CVEs that do not match the description we're interested in. if not re.search(opt.description, text): continue
check_dirs = [cve_lib.active_dir, cve_lib.retired_dir, cve_lib.ignored_dir] for dirname in check_dirs: if len(args)==0: items = glob.glob('%s/CVE-*' % (dirname)) else: items = [y for y in ['%s/%s' % (dirname, x) for x in args] if os.path.exists(y)] items = sorted(items) for cvefile in items: cvelist += [cvefile] # Load and keep only kernel CVEs if opt.debug: print >>sys.stderr, "Loading CVEs ..." for cvefile in cvelist: state, cve = cvefile.split('/')[-2:] info = cve_lib.load_cve(cvefile) keep = False for pkg in opt.packages: if pkg in info['pkgs']: keep = True break if keep: cves[cve] = info if state == "active": active.add(cve) pkgs = usn_lib.packages_dict(db, opt.packages, opt=opt) touched = set() # Build map of pkgs-updated-per-usn updated_packages = dict()
else: cves = db[usn]['cves'] for cve in cves: if ' CVE' in cve: print("Bad CVE name (%s) in USN-%s" % (cve, usn), file=sys.stderr) #if not cve.startswith('CVE-'): # print("Skipped weird CVE in USN-%s: %s" % (usn,cve), file=sys.stderr) # continue ## Skip checking CVEs that were reverted for a given USN #if usn in reverted and cve in reverted[usn]: # continue if cve.startswith('CVE') and cve not in info: try: info.setdefault(cve, cve_lib.load_cve(cve_lib.find_cve(cve))) except Exception as e: print("Skipping %s: %s" % (cve, str(e)), file=sys.stderr) continue for rel in db[usn]['releases']: if rel not in releases: continue if 'sources' not in db[usn]['releases'][rel]: if 'archs' not in db[usn]['releases'][rel]: # Old USN, lacks either sources or archs, use first binary pkg = db[usn]['releases'][rel]['binaries'].keys()[0] report(db[usn]['timestamp'], usn, cve, pkg, rel, _get_cve_priority(cve, pkg, rel)) else: