Merge ~litios/ubuntu-cve-tracker:aliases-v2 into ubuntu-cve-tracker:master

Proposed by David Fernandez Gonzalez
Status: Merged
Merged at revision: 6429624c17b76980ce95094140c2527fda8b1def
Proposed branch: ~litios/ubuntu-cve-tracker:aliases-v2
Merge into: ubuntu-cve-tracker:master
Diff against target: 264 lines (+116/-39)
5 files modified
scripts/active_edit (+12/-4)
scripts/check-cves (+18/-1)
scripts/check-syntax (+24/-24)
scripts/check-syntax-fixup (+29/-4)
scripts/source_map.py (+33/-6)
Reviewer Review Type Date Requested Status
Alex Murray Approve
Review via email: mp+437199@code.launchpad.net

Description of the change

This MR is to use aliases the other way around as it is right now:
* supported.txt will contain the name of the package in the subproject
* aliases.yaml will contain the aliases for the package name in Ubuntu

Example:

$ cat subprojects/soss/conda-focal/supported.txt| grep cryptography
cryptography
$ cat subprojects/soss/conda-focal/aliases.yaml
---
cryptography: [python-cryptography]

When doing triage, we want to make the process as easy as possible; therefore, the tool will expect that the user always provides the Ubuntu name of the package. It will warn the user if using the subproject name instead of the Ubuntu one (if it exists), as this will break any other aliases in other subprojects.

In case the package doesn't exist in Ubuntu, the tool will warn the user that it exists in a subproject and the person doing triage can provide the subproject name(s) so the CVE gets created.

Example output with check-cves and check-syntax: https://pastebin.canonical.com/p/PyzT5tvjmP/

To post a comment you must log in.
Revision history for this message
David Fernandez Gonzalez (litios) wrote :

It seems like the preview diff is broken, all the changes to CVEs are already merged in master.

Revision history for this message
Alex Murray (alexmurray) wrote :

A few questions inline.

review: Needs Fixing
Revision history for this message
David Fernandez Gonzalez (litios) wrote :

Thanks for the input Alex!

I was relying too much on the user to do the manual work of figuring out the right alias when triaging.

I added some new commits to make it more transparent.

About the multi-versioned packages Steve mentioned, the last commit should also fix the issue.

Revision history for this message
David Fernandez Gonzalez (litios) wrote (last edit ):

I added a final commit to deal with aliases in SOSS.

SOSS package names have the format PACKAGE|VERSION, and that's what the contents of supported.txt are.

Right now, the format of aliases.yaml would be something like this to match it:

"cryptography|1.0.0": ["python-cryptography"],
"cryptography|2.0.0": ["python-cryptography"],
...

but really, whatever is after the | doesn't seem useful for aliases, as the package is always the same. So the proposed format from @ccdm94 was:

"cryptography": ["python-cryptography"],

and that should cover all of the "cryptography|VERSION" listed in `supported.txt`.

Testing: https://pastebin.canonical.com/p/fXYYYN9jmV/

Revision history for this message
Alex Murray (alexmurray) wrote :

LGTM - but one minor query about whether we even need check-syntax-fixup anymore and hence could these changes to it be removed and the file deleted instead?

review: Approve
Revision history for this message
Alex Murray (alexmurray) wrote :

Actually as pointed out by mdeslaur, check-syntax-fixup is still useful for a bunch of use-cases so please ignore those comments.

Revision history for this message
David Fernandez Gonzalez (litios) wrote :

Thanks Alex!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/scripts/active_edit b/scripts/active_edit
index 9d0df27..ec36cfe 100755
--- a/scripts/active_edit
+++ b/scripts/active_edit
@@ -43,6 +43,8 @@ for release in cve_lib.all_releases:
43 source_releases.append(release)43 source_releases.append(release)
44source = source_map.load(releases=source_releases, skip_eol_releases=False)44source = source_map.load(releases=source_releases, skip_eol_releases=False)
4545
46added_rel_pkg = []
47
46def pkg_in_rel(pkg,rel):48def pkg_in_rel(pkg,rel):
47 if rel in ['upstream']:49 if rel in ['upstream']:
48 return True50 return True
@@ -88,10 +90,12 @@ def _add_pkg(p, fp, fixed, parent, embargoed):
88 if len(fixed[p]) > 2:90 if len(fixed[p]) > 2:
89 fixed_in_release_version = fixed[p][2]91 fixed_in_release_version = fixed[p][2]
90 for rel in ['upstream'] + list(source.keys()):92 for rel in ['upstream'] + list(source.keys()):
93 aliases = source_map.get_aliases_of_ubuntu_package(source, p, rel)
94
91 # determine default state but override this if pkg_db has a95 # determine default state but override this if pkg_db has a
92 # better one96 # better one
93 state = "needs-triage"97 state = "needs-triage"
94 if not pkg_in_rel(p, rel):98 if not pkg_in_rel(p, rel) and not aliases:
95 # package doesn't exist in this release - see if it wants a99 # package doesn't exist in this release - see if it wants a
96 # DNE entry100 # DNE entry
97 if release_wants_dne(rel):101 if release_wants_dne(rel):
@@ -128,9 +132,13 @@ def _add_pkg(p, fp, fixed, parent, embargoed):
128 print('%s_%s: %s' % (rel, p, state), file=fp)132 print('%s_%s: %s' % (rel, p, state), file=fp)
129 # TODO: figure out how to store subproject details for embargoed CVEs133 # TODO: figure out how to store subproject details for embargoed CVEs
130 elif not embargoed:134 elif not embargoed:
131 # add this to subprojects for rel135 pkgs_to_add = aliases if aliases else [p]
132 with open(os.path.join(cve_lib.get_external_subproject_cve_dir(rel), cve), "a") as f:136 for pkg in pkgs_to_add:
133 print('%s_%s: %s' % (rel, p, state), file=f)137 rel_pkgname = rel + '/' + pkg
138 if not rel_pkgname in added_rel_pkg:
139 with open(os.path.join(cve_lib.get_external_subproject_cve_dir(rel), cve), "a") as f:
140 print('%s_%s: %s' % (rel, pkg, state), file=f)
141 added_rel_pkg.append(rel_pkgname)
134142
135def add_pkg(p, fp, fixed, parent, embargoed):143def add_pkg(p, fp, fixed, parent, embargoed):
136 # skip packages which don't actually exist in any release144 # skip packages which don't actually exist in any release
diff --git a/scripts/check-cves b/scripts/check-cves
index 6eb9f58..2bc15d2 100755
--- a/scripts/check-cves
+++ b/scripts/check-cves
@@ -884,9 +884,26 @@ class CVEHandler(xml.sax.handler.ContentHandler):
884 external_subprojects = {}884 external_subprojects = {}
885 for subproject in cve_lib.external_releases:885 for subproject in cve_lib.external_releases:
886 if subproject in source:886 if subproject in source:
887 aliases = source_map.get_all_aliases(source, subproject)
887 for hint in software_hints_from_cve_description:888 for hint in software_hints_from_cve_description:
888 if hint in source[subproject] and hint not in common_words:889 if hint in common_words:
890 continue
891
892 if hint in source[subproject]:
893 if 'aliases' in source[subproject][hint]:
894 external_subprojects.setdefault(subproject, set()).add(','.join(source[subproject][hint]['aliases']))
895 else:
896 external_subprojects.setdefault(subproject, set()).add(hint)
897 elif hint in aliases:
889 external_subprojects.setdefault(subproject, set()).add(hint)898 external_subprojects.setdefault(subproject, set()).add(hint)
899 else:
900 pkgs = source_map.get_packages_from_generic_name(source, hint, subproject)
901 for pkg in pkgs:
902 if 'aliases' in source[subproject][pkg]:
903 external_subprojects.setdefault(subproject, set()).add(','.join(source[subproject][pkg]['aliases']))
904 else:
905 external_subprojects.setdefault(subproject, set()).add(pkg)
906
890 return external_subprojects907 return external_subprojects
891908
892 def display_cve(self, cve, file=sys.stdout, line_prefix=None, wrap_desc=False):909 def display_cve(self, cve, file=sys.stdout, line_prefix=None, wrap_desc=False):
diff --git a/scripts/check-syntax b/scripts/check-syntax
index def63e3..4fb0cf8 100755
--- a/scripts/check-syntax
+++ b/scripts/check-syntax
@@ -429,35 +429,35 @@ for cve in args:
429429
430 # Check aliases430 # Check aliases
431 for rel in all_required_releases:431 for rel in all_required_releases:
432 if rel in source and pkg in source[rel] and \432 if rel in source:
433 'aliases' in source[rel][pkg]:433 aliases = source_map.get_aliases_of_ubuntu_package(source, pkg, rel)
434 aliases_releases.add(rel)434 if aliases:
435435 if rel in listed_releases and pkg \
436 # This package-release uses aliases,436 not in aliases:
437 # it shouldn't be listed
438 if rel in listed_releases and pkg \
439 not in source[rel][pkg]['aliases']:
440 filename = srcmap["pkgs"][pkg][nearby_rel][0]
441 linenum = srcmap["pkgs"][pkg][nearby_rel][1]
442 print(
443 "%s: %d: package '%s' not in '%s'"
444 % (filename, linenum, pkg, rel),
445 file=sys.stderr,
446 )
447
448 failed = 0
449 for alias in source[rel][pkg]['aliases']:
450 if alias not in data["pkgs"].keys():
451 filename = srcmap["pkgs"][pkg][nearby_rel][0]437 filename = srcmap["pkgs"][pkg][nearby_rel][0]
452 linenum = srcmap["pkgs"][pkg][nearby_rel][1]438 linenum = srcmap["pkgs"][pkg][nearby_rel][1]
453 print(439 print(
454 "%s: %d: %s missing release '%s'"440 "%s: %d: package '%s' not in '%s'"
455 # put the error on a line near where this entry should go441 % (filename, linenum, pkg, rel),
456 % (filename, linenum, alias, rel),
457 file=sys.stderr,442 file=sys.stderr,
458 )443 )
459 cve_okay = False444
460 failed += 1445 aliases_releases.add(rel)
446
447 # This package-release uses aliases,
448 # it shouldn't be listed
449
450 for alias in aliases:
451 if alias not in data["pkgs"].keys():
452 filename = srcmap["pkgs"][pkg][nearby_rel][0]
453 linenum = srcmap["pkgs"][pkg][nearby_rel][1]
454 print(
455 "%s: %d: %s missing release '%s'"
456 # put the error on a line near where this entry should go
457 % (filename, linenum, alias, rel),
458 file=sys.stderr,
459 )
460 cve_okay = False
461461
462 missing_releases = all_required_releases - listed_releases - aliases_releases462 missing_releases = all_required_releases - listed_releases - aliases_releases
463 nearby_rel = list(listed_releases - missing_releases)[0]463 nearby_rel = list(listed_releases - missing_releases)[0]
diff --git a/scripts/check-syntax-fixup b/scripts/check-syntax-fixup
index c7c77c2..697368c 100755
--- a/scripts/check-syntax-fixup
+++ b/scripts/check-syntax-fixup
@@ -59,11 +59,31 @@ def delete_from_file(filename: str, linenum: int, dryrun=False, verbose=False):
59 else:59 else:
60 print("%s: %d: would delete this line" % (os.path.relpath(filename), linenum))60 print("%s: %d: would delete this line" % (os.path.relpath(filename), linenum))
6161
62
63def identify_subproject_line_number(filename: str, pkg: str, rel: str):
64 # file may not already exist
65 contents = []
66 try:
67 with open(filename, "r") as f:
68 contents = f.readlines()
69 except FileNotFoundError:
70 pass
71
72 for linenum,line in enumerate(contents):
73 line_rel, line_pkg = line.split(":")[0].split('_')
74 if pkg == line_pkg and rel == line_rel:
75 return linenum + 1
76
77 return -1
78
62def get_pkg_rel_from_msg(msg):79def get_pkg_rel_from_msg(msg):
63 parts = msg.split(" ")80 parts = msg.split(" ")
64 if 'DOES exist' in msg or 'not in' in msg:81 if 'DOES exist' in msg or 'not in' in msg:
65 pkg = parts[1].replace("'", "")82 pkg = parts[1].replace("'", "")
66 rel = parts[-1].replace("'", "")83 rel = parts[-1].replace("'", "")
84 elif 'unknown package' in msg:
85 pkg = parts[2].replace("'", "")
86 rel = parts[-1].replace("'", "")
67 else:87 else:
68 pkg = parts[0]88 pkg = parts[0]
69 rel = parts[-1].replace("'", "")89 rel = parts[-1].replace("'", "")
@@ -153,8 +173,11 @@ for line in args.infile:
153 cve = os.path.join(173 cve = os.path.join(
154 cve_lib.get_external_subproject_cve_dir(rel), os.path.basename(cve)174 cve_lib.get_external_subproject_cve_dir(rel), os.path.basename(cve)
155 )175 )
156 # linenum is only relevant to the original cve file176 linenum = identify_subproject_line_number(cve, pkg, rel)
157 linenum = 1177 if linenum == -1:
178 if 'DOES exist' in msg:
179 continue
180 linenum = 1 # We are inserting
158181
159 # Remove the 'DNE' line before adding the new one182 # Remove the 'DNE' line before adding the new one
160 if 'DOES exist' in msg:183 if 'DOES exist' in msg:
@@ -171,8 +194,10 @@ for line in args.infile:
171 cve = os.path.join(194 cve = os.path.join(
172 cve_lib.get_external_subproject_cve_dir(rel), os.path.basename(cve)195 cve_lib.get_external_subproject_cve_dir(rel), os.path.basename(cve)
173 )196 )
174 # linenum is only relevant to the original cve file197 linenum = identify_subproject_line_number(cve, pkg, rel)
175 linenum = 1198 if linenum == -1:
199 print(line, file=sys.stderr)
200 continue
176201
177 # delete this line since202 # delete this line since
178 delete_from_file(cve, linenum, args.dry_run, args.verbose)203 delete_from_file(cve, linenum, args.dry_run, args.verbose)
diff --git a/scripts/source_map.py b/scripts/source_map.py
index 311c1f6..616c5ec 100755
--- a/scripts/source_map.py
+++ b/scripts/source_map.py
@@ -423,6 +423,29 @@ def get_built_using_header():
423 header += "\n" + "-" * 78423 header += "\n" + "-" * 78
424 return header424 return header
425425
426def get_all_aliases(sources, rel):
427 aliases = []
428 for pkg in sources[rel]:
429 if 'aliases' in sources[rel][pkg]:
430 for alias in sources[rel][pkg]['aliases']:
431 aliases.append(alias)
432 return aliases
433
434def get_aliases_of_ubuntu_package(sources, pkg_name, rel_name):
435 aliases = []
436 for rel in sources:
437 for pkg in sources[rel]:
438 if rel == rel_name and 'aliases' in sources[rel][pkg]:
439 if pkg_name in sources[rel][pkg]['aliases']:
440 aliases.append(pkg)
441 return aliases
442
443def get_packages_from_generic_name(sources, generic_name, rel):
444 pkgs = []
445 for pkg in sources[rel]:
446 if 'generic_name' in sources[rel][pkg] and sources[rel][pkg]['generic_name'] == generic_name:
447 pkgs.append(pkg)
448 return pkgs
426449
427def load_subprojects_lists(releases=None):450def load_subprojects_lists(releases=None):
428 map = dict()451 map = dict()
@@ -471,17 +494,21 @@ def load_subprojects_lists(releases=None):
471 map[rel][pkg]['pocket'] = ''494 map[rel][pkg]['pocket'] = ''
472 map[rel][pkg]['section'] = 'main'495 map[rel][pkg]['section'] = 'main'
473496
497 if '|' in pkg:
498 main_package_name = pkg.split('|')[0]
499 map[rel][pkg]['generic_name'] = main_package_name
500
474 if 'aliases' in details:501 if 'aliases' in details:
475 with open(details['aliases'], 'r') as file:502 with open(details['aliases'], 'r') as file:
476 aliases = yaml.safe_load(file)503 aliases = yaml.safe_load(file)
477504
478 for pkg in aliases:505 for pkg in aliases:
479 if pkg in map[rel]:506 for src_pkg in map[rel]:
480 map[rel][pkg]['aliases'] = aliases[pkg]507 if pkg == src_pkg or \
481 #else:508 ('generic_name' in map[rel][src_pkg] and pkg == map[rel][src_pkg]['generic_name']):
482 # print("WARN: pkg %s found in aliases but not in supported list for %s. Skipping" % (pkg, rel))509 map[rel][src_pkg]['aliases'] = aliases[pkg]
483 else:510 #else:
484 pass511 # print("WARN: pkg %s found in aliases but not in supported list for %s. Skipping" % (pkg, rel))
485512
486 return map513 return map
487514

Subscribers

People subscribed via source and target branches