[Git][security-tracker-team/security-tracker][master] lts-cve-triage: from_elts: add annotations

Sylvain Beucler (@beuc) gitlab at salsa.debian.org
Tue Aug 12 19:58:12 BST 2025



Sylvain Beucler pushed to branch master at Debian Security Tracker / security-tracker


Commits:
662b81aa by Sylvain Beucler at 2025-08-12T20:58:07+02:00
lts-cve-triage: from_elts: add annotations

This report is still new and generates noise.

It is tempting to filter as in 'from_next_lts' but this would make
both reports identical.

Annotate the output for now to better understand the report and avoid
FD from getting the wrong idea.
See also: https://lists.debian.org/debian-lts/2025/08/msg00022.html

Also:
- make annotations generic rather than my old hack in the output code
- make the test about explicit stable/oldstable update more robust.
- clarify 'triage_possible_missed_fixes' as 'from_next_lts'.

- - - - -


1 changed file:

- bin/lts-cve-triage.py


Changes:

=====================================
bin/lts-cve-triage.py
=====================================
@@ -30,6 +30,7 @@ import sys
 import argparse
 import collections
 import re
+from apt_pkg import version_compare
 
 from tracker_data import TrackerData
 from unsupported_packages import UnsupportedPackages, LimitedSupportPackages
@@ -84,18 +85,18 @@ LIST_NAMES = (
      .format(**RELEASES)),
     ('triage_other',
      'Other issues to triage (no special status)'),
-    ('triage_possible_missed_fixes',
+    ('from_next_lts',
      ('Issues postponed for {lts}, but already fixed in {next_lts} via DSA or point releases')
      .format(**RELEASES)),
     ('unexpected_nodsa',
      ('Issues tagged no-dsa in {lts} that are open in {next_lts}')
      .format(**RELEASES)),
-    ('undetermined',
-     ('Undetermined issues in {lts}').format(**RELEASES)),
     ('to_forward',
      ('Issues fixed in {lts} but not in {next_lts} [caution: new report]').format(**RELEASES)),
     ('from_elts',
      ('Issues fixed in {prev_lts} and {next_lts} but not in {lts} [caution: new report]').format(**RELEASES)),
+    ('undetermined',
+     ('Undetermined issues in {lts}').format(**RELEASES)),
 )
 
 lists = collections.defaultdict(lambda: collections.defaultdict(lambda: []))
@@ -119,11 +120,24 @@ limited = LimitedSupportPackages(codename=RELEASES['lts'],
 unsupported_re = re.compile('|'.join(unsupported))
 limited_re = re.compile('|'.join(limited))
 
+secupdate_re = re.compile(r'deb\d+u\d+$')
+
 pu_expected = PointUpdateParser.parseNextPointUpdateStable()
 
-def add_to_list(key, pkg, issue):
+def add_to_list(key, pkg, cve, annotation=''):
     assert key in [l[0] for l in LIST_NAMES]
-    lists[key][pkg].append(issue)
+    lists[key][pkg].append((cve, annotation))
+
+def is_next_lts_fix_explicit(issue):
+    """Was the fix in stable/oldstable explicit or inherited from unstable?"""
+    next_lts_fixed_version = issue.data['releases'][RELEASES['next_lts']]['fixed_version']
+    if 'sid' in issue.data['releases']:
+        unstable_version = issue.data['releases']['sid']['fixed_version']
+        is_explicit_fix = version_compare(next_lts_fixed_version, unstable_version) < 0
+    else:
+        # package removed from sid, use heuristic
+        is_explicit_fix = re.search(secupdate_re, next_lts_fixed_version)
+    return bool(is_explicit_fix)
 
 
 for pkg in tracker.iterate_packages():
@@ -172,16 +186,15 @@ for pkg in tracker.iterate_packages():
         elif status_in_lts.status == 'ignored':
             if (status_in_lts.reason == 'no-dsa' and
                     status_in_next_lts.status == 'open'):
-                add_to_list('unexpected_nodsa', pkg, issue)
+                add_to_list('unexpected_nodsa', pkg, issue,
+                            issue.data['releases'][RELEASES['lts']]['nodsa_reason'])
             elif (status_in_lts.reason == 'no-dsa' and
                     status_in_next_lts.status == 'resolved'):
-                # include fixes from DSA or stable/oldstable point releases
-                # exclude issues explicitly ignored, and old fixes back in unstable
+                # include explicit fixes from DSA or stable/oldstable point releases
+                # exclude issues explicitly ignored, and old fixes back from unstable
                 nodsa_reason = issue.data['releases'][RELEASES['lts']]['nodsa_reason']
-                fixed_version = issue.data['releases'][RELEASES['next_lts']]['fixed_version']
-                if (nodsa_reason != 'ignored' and
-                    ('~deb' in fixed_version or '+deb' in fixed_version)):
-                    add_to_list('triage_possible_missed_fixes', pkg, issue)
+                if is_next_lts_fix_explicit(issue) and nodsa_reason != 'ignored':
+                    add_to_list('from_next_lts', pkg, issue)
             elif status_in_lts.reason == 'undetermined':
                 add_to_list('undetermined', pkg, issue)
 
@@ -200,11 +213,15 @@ for pkg in tracker_elts.iterate_packages():
         status_in_next_lts = issue.get_status(RELEASES['next_lts'])
         status_in_elts = issue.get_status(RELEASES['prev_lts'])
 
-        if (status_in_elts.status == 'resolved' and status_in_elts.reason != 'fixed in 0'
+        if (    status_in_elts.status == 'resolved'
+            and status_in_elts.reason != 'fixed in 0'
             and status_in_next_lts.status == 'resolved'
             and status_in_lts.status not in ('resolved', 'not-affected')
             and status_in_lts.urgency != 'unimportant'):
-            add_to_list('from_elts', pkg, issue)
+            annotation = issue.data['releases'][RELEASES['lts']]['nodsa_reason']
+            if not is_next_lts_fix_explicit(issue):
+                annotation += ' [{next_lts} fix from unstable]'.format(**RELEASES)
+            add_to_list('from_elts', pkg, issue, annotation)
 
 
 for key, desc in LIST_NAMES:
@@ -224,18 +241,16 @@ for key, desc in LIST_NAMES:
             colored('{}source-package/{}'.format(TRACKER_LINK_URL, pkg), 'blue'),
         ))
         nb_issues = 0
-        for x in sorted(lists[key][pkg], key=lambda x: x.name):
+        for (cve, annotation) in sorted(lists[key][pkg], key=lambda x: x[0].name):
             # limit very large lists such as linux'
             nb_issues += 1
             if nb_issues > 10:
                 print('  - ...')
                 break
-            url = '{}{}'.format(TRACKER_LINK_URL, x.name)
+            url = '{}{}'.format(TRACKER_LINK_URL, cve.name)
             print('  - {:<16s}  {} {}'.format(
-                x.name,
+                cve.name,
                 colored(url, 'blue'),
-                (key == 'unexpected_nodsa' and
-                    x.data['releases'][RELEASES['lts']]['nodsa_reason']
-                    or '')),
+                annotation)
             )
     print('')



View it on GitLab: https://salsa.debian.org/security-tracker-team/security-tracker/-/commit/662b81aa406e4c0d38f0b878296a047a50e6a5ea

-- 
View it on GitLab: https://salsa.debian.org/security-tracker-team/security-tracker/-/commit/662b81aa406e4c0d38f0b878296a047a50e6a5ea
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-security-tracker-commits/attachments/20250812/02e6c384/attachment-0001.htm>


More information about the debian-security-tracker-commits mailing list