[Reportbug-maint] Bug#878088: Bug#878088: reportbug: please inform security and lts teams about security update regressions
Guido Günther
agx at sigxcpu.org
Mon Jan 29 08:30:59 UTC 2018
Hi Markus,
thanks for pursuing this! Some minor nitpicks:
On Mon, Jan 29, 2018 at 12:11:03AM +0100, Markus Koschany wrote:
[..snip..]
> + if utils.is_security_update(package, pkgversion):
> + if ui.yes_no('Do you want to report a regression because of a security update? ',
> + 'Yes, please inform the LTS and security teams.',
> + 'No or I am not sure.', True):
> + regex = re.compile('(\+|~)deb(\d+)u(\d+)')
> + secversion = regex.search(pkgversion)
> + distnumber = secversion.group(2)
> + support = 'none'
Using
support = None
is a bit more pythonic.
> + email_address = []
> + try:
> + r = requests.get('https://security-tracker.debian.org/tracker/distributions.json',
> + timeout=self.options.timeout)
This will not catch 404 or similar http status codes. If you don't care
about the type of error you can just do …
r.raise_for_status()
… ff you dont handle the error this …
> + data = r.json()
… will fail like:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/requests/models.py", line 892, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/lib/python2.7/dist-packages/simplejson/__init__.py", line 518, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/dist-packages/simplejson/decoder.py", line 370, in decode
obj, end = self.raw_decode(s)
File "/usr/lib/python2.7/dist-packages/simplejson/decoder.py", line 400, in raw_decode
return self.scan_once(s, idx=_w(s, idx).end())
simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
> + for key, value in data.items():
> + if distnumber == value['major-version']:
> + if value['support']:
> + support = value['support']
> + if value['contact']:
> + email_address = value['contact']
> +
> + if support != 'none':
(With the abouve "support = None"):
if support is not None:
> + listcc += [email_address]
> +
… The raise_for_status exception is caught here alreadyx since
requests.exceptions.HTTPError is a subclass of
requests.exceptions.RequestException):
> + except requests.exceptions.RequestException:
> + ewrite('Unable to connect to security-tracker.debian.org.\n'
> + 'Please try again later or contact the LTS or security team via email directly.\n')
> +
It would also improve readability if this whole code block moved into a get_security_contact()
function.
Cheers,
-- Guido
> if severity and rtype:
> severity = debbugs.convert_severity(severity, rtype)
>
> diff -Nru reportbug-7.1.8/debian/changelog reportbug-7.1.8+nmu1/debian/changelog
> --- reportbug-7.1.8/debian/changelog 2017-12-29 05:25:43.000000000 +0100
> +++ reportbug-7.1.8+nmu1/debian/changelog 2018-01-23 20:43:14.000000000 +0100
> @@ -1,3 +1,10 @@
> +reportbug (7.1.8+nmu1) UNRELEASED; urgency=medium
> +
> + * Non-maintainer upload.
> + *
> +
> + -- Markus Koschany <apo at debian.org> Tue, 23 Jan 2018 20:43:14 +0100
> +
> reportbug (7.1.8) unstable; urgency=medium
>
> * reportbug/debbugs.py
> diff -Nru reportbug-7.1.8/reportbug/utils.py reportbug-7.1.8+nmu1/reportbug/utils.py
> --- reportbug-7.1.8/reportbug/utils.py 2017-12-29 05:25:43.000000000 +0100
> +++ reportbug-7.1.8+nmu1/reportbug/utils.py 2018-01-23 20:43:14.000000000 +0100
> @@ -39,6 +39,8 @@
> import socket
> import subprocess
> import pipes
> +import apt
> +import gzip
>
> from .urlutils import open_url
> from string import ascii_letters, digits
> @@ -1333,3 +1335,80 @@
> break
>
> return lsminfo
> +
> +
> +def is_security_update(pkgname, pkgversion):
> + """Determine whether a given package is a security update.
> +
> + Detection of security update versions works most reliably if the
> + package version under investigation is the currently installed
> + version. If this is not the case, the probability of false
> + negatives increases.
> +
> + Parameters
> + ----------
> + pkgname : str
> + package name
> + pkgversion : str
> + package version
> +
> + Returns
> + -------
> + bool
> + True if there is evidence that this version is a security
> + update, otherwise False
> + """
> + # Check 1:
> + # If it does not follow the debXuY version number pattern, it is
> + # definitely no security update.
> + #
> + # This check is not sufficient to detect security updates reliably,
> + # since other stable updates also use the same version pattern.
> + regex = re.compile('(\+|~)deb(\d+)u(\d+)')
> + secversion = regex.search(pkgversion)
> + if not secversion:
> + return False
> +
> + # Check 2:
> + # If the package comes from the Debian-Security package source, it
> + # is definitely a security update.
> + #
> + # This check does not identify all security updates, since some of
> + # them are distributed through the normal channels as part of a
> + # stable release update.
> + try:
> + p = apt.Cache()[pkgname]
> + if 'Debian-Security' in [o.label for o in
> + p.versions[pkgversion].origins]:
> + return True
> + except:
> + pass
> +
> + # Check 3:
> + # Inspect the package changelog if it mentions any vulnerability,
> + # identified by a CVE number, in the section of the latest version.
> +
> + cl = None
> + for cl in ['/usr/share/doc/{}/changelog.Debian.gz'.format(pkgname),
> + '/usr/share/doc/{}/changelog.gz'.format(pkgname)]:
> + if os.path.exists(cl):
> + break
> +
> + try:
> + with gzip.open(cl, 'rt') as f:
> + ln = f.readline()
> + if pkgversion not in ln:
> + raise KeyError
> +
> + for ln in f.readlines():
> + # stop reading at the end of the first section
> + if ln.rstrip() != '' and (ln.startswith(' -- ') or not ln.startswith(' ')):
> + break
> +
> + if 'CVE-20' in ln.upper():
> + return True
> + except:
> + pass
> +
> + # guess 'no security update, but normal stable update' by default
> + return False
More information about the Reportbug-maint
mailing list