[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#943846: marked as done (buster-pu: package python-cryptography/2.6.1-3+deb10u2)



Your message dated Sat, 16 Nov 2019 10:08:47 +0000
with message-id <83c9ffab6f08361485f70dda4733a7a24aeec09b.camel@adam-barratt.org.uk>
and subject line Closing bugs for 10.2 point release fixes
has caused the Debian Bug report #943846,
regarding buster-pu: package python-cryptography/2.6.1-3+deb10u2
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
943846: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=943846
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu

(This is a followup update on top of the +deb10u1 already in s-p-u,
I've reached out to Tristan beforehand)

Attached debdiff fixes a memory leak in python-cryptography, which
was noticed in an ACME-related service (https://wikitech.wikimedia.org/wiki/Acme-chief)
running on Buster. It has been verified that the updated packages
fix the memory leak (and are otherwise working fine as well).

Debdiff below.

Cheers,
        Moritz

diff -Nru python-cryptography-2.6.1/debian/changelog python-cryptography-2.6.1/debian/changelog
--- python-cryptography-2.6.1/debian/changelog	2019-09-30 20:55:00.000000000 +0200
+++ python-cryptography-2.6.1/debian/changelog	2019-10-18 16:08:59.000000000 +0200
@@ -1,3 +1,13 @@
+python-cryptography (2.6.1-3+deb10u2) buster; urgency=medium
+
+  * Cherrypick 92241410b5b0591d849443b3023992334a4be0a2 and
+    9a22851fab924fd58482fdad3f8dd23dc3987f91 from upstream which
+    addresses a memory leak triggerable when parsing x509
+    certificate extensions like AIA, thanks to Valentin
+    Gutierrez for the report (Closes: #941413)
+
+ -- Moritz Mühlenhoff <jmm@debian.org>  Fri, 18 Oct 2019 16:08:59 +0200
+
 python-cryptography (2.6.1-3+deb10u1) buster; urgency=medium
 
   * Non-maintainer upload.
diff -Nru python-cryptography-2.6.1/debian/patches/aia-memleak-1.patch python-cryptography-2.6.1/debian/patches/aia-memleak-1.patch
--- python-cryptography-2.6.1/debian/patches/aia-memleak-1.patch	1970-01-01 01:00:00.000000000 +0100
+++ python-cryptography-2.6.1/debian/patches/aia-memleak-1.patch	2019-10-18 16:08:35.000000000 +0200
@@ -0,0 +1,94 @@
+From 92241410b5b0591d849443b3023992334a4be0a2 Mon Sep 17 00:00:00 2001
+From: Paul Kehrer <paul.l.kehrer@gmail.com>
+Date: Thu, 11 Apr 2019 20:57:13 +0800
+Subject: [PATCH] fix a memory leak in AIA parsing (#4836)
+
+* fix a memory leak in AIA parsing
+
+* oops can't remove that
+---
+ src/_cffi_src/openssl/x509v3.py               |  3 +++
+ .../hazmat/backends/openssl/decode_asn1.py    |  9 +++++++-
+ tests/hazmat/backends/test_openssl_memleak.py | 21 ++++++++++++++++++-
+ 3 files changed, 31 insertions(+), 2 deletions(-)
+
+diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py
+index 193d2e233b..5968120652 100644
+--- a/src/_cffi_src/openssl/x509v3.py
++++ b/src/_cffi_src/openssl/x509v3.py
+@@ -177,6 +177,7 @@
+ typedef void (*sk_GENERAL_NAME_freefunc)(GENERAL_NAME *);
+ typedef void (*sk_DIST_POINT_freefunc)(DIST_POINT *);
+ typedef void (*sk_POLICYINFO_freefunc)(POLICYINFO *);
++typedef void (*sk_ACCESS_DESCRIPTION_freefunc)(ACCESS_DESCRIPTION *);
+ """
+ 
+ 
+@@ -228,6 +229,8 @@
+     Cryptography_STACK_OF_ACCESS_DESCRIPTION *, int
+ );
+ void sk_ACCESS_DESCRIPTION_free(Cryptography_STACK_OF_ACCESS_DESCRIPTION *);
++void sk_ACCESS_DESCRIPTION_pop_free(Cryptography_STACK_OF_ACCESS_DESCRIPTION *,
++                              sk_ACCESS_DESCRIPTION_freefunc);
+ int sk_ACCESS_DESCRIPTION_push(Cryptography_STACK_OF_ACCESS_DESCRIPTION *,
+                                ACCESS_DESCRIPTION *);
+ 
+diff --git a/src/cryptography/hazmat/backends/openssl/decode_asn1.py b/src/cryptography/hazmat/backends/openssl/decode_asn1.py
+index 773189d4f8..75d5844bc1 100644
+--- a/src/cryptography/hazmat/backends/openssl/decode_asn1.py
++++ b/src/cryptography/hazmat/backends/openssl/decode_asn1.py
+@@ -379,7 +379,14 @@ def _decode_authority_key_identifier(backend, akid):
+ 
+ def _decode_authority_information_access(backend, aia):
+     aia = backend._ffi.cast("Cryptography_STACK_OF_ACCESS_DESCRIPTION *", aia)
+-    aia = backend._ffi.gc(aia, backend._lib.sk_ACCESS_DESCRIPTION_free)
++    aia = backend._ffi.gc(
++        aia,
++        lambda x: backend._lib.sk_ACCESS_DESCRIPTION_pop_free(
++            x, backend._ffi.addressof(
++                backend._lib._original_lib, "ACCESS_DESCRIPTION_free"
++            )
++        )
++    )
+     num = backend._lib.sk_ACCESS_DESCRIPTION_num(aia)
+     access_descriptions = []
+     for i in range(num):
+diff --git a/tests/hazmat/backends/test_openssl_memleak.py b/tests/hazmat/backends/test_openssl_memleak.py
+index ed22b5db9e..f9ae1c46b9 100644
+--- a/tests/hazmat/backends/test_openssl_memleak.py
++++ b/tests/hazmat/backends/test_openssl_memleak.py
+@@ -210,7 +210,7 @@ class TestOpenSSLMemoryLeaks(object):
+     @pytest.mark.parametrize("path", [
+         "x509/PKITS_data/certs/ValidcRLIssuerTest28EE.crt",
+     ])
+-    def test_x509_certificate_extensions(self, path):
++    def test_der_x509_certificate_extensions(self, path):
+         assert_no_memory_leaks(textwrap.dedent("""
+         def func(path):
+             from cryptography import x509
+@@ -226,6 +226,25 @@ def func(path):
+             cert.extensions
+         """), [path])
+ 
++    @pytest.mark.parametrize("path", [
++        "x509/cryptography.io.pem",
++    ])
++    def test_pem_x509_certificate_extensions(self, path):
++        assert_no_memory_leaks(textwrap.dedent("""
++        def func(path):
++            from cryptography import x509
++            from cryptography.hazmat.backends.openssl import backend
++
++            import cryptography_vectors
++
++            with cryptography_vectors.open_vector_file(path, "rb") as f:
++                cert = x509.load_pem_x509_certificate(
++                    f.read(), backend
++                )
++
++            cert.extensions
++        """), [path])
++
+     def test_x509_csr_extensions(self):
+         assert_no_memory_leaks(textwrap.dedent("""
+         def func():
diff -Nru python-cryptography-2.6.1/debian/patches/aia-memleak-2.patch python-cryptography-2.6.1/debian/patches/aia-memleak-2.patch
--- python-cryptography-2.6.1/debian/patches/aia-memleak-2.patch	1970-01-01 01:00:00.000000000 +0100
+++ python-cryptography-2.6.1/debian/patches/aia-memleak-2.patch	2019-10-18 16:08:35.000000000 +0200
@@ -0,0 +1,181 @@
+From 9a22851fab924fd58482fdad3f8dd23dc3987f91 Mon Sep 17 00:00:00 2001
+From: Paul Kehrer <paul.l.kehrer@gmail.com>
+Date: Sat, 18 May 2019 16:37:54 -0400
+Subject: [PATCH] fix aia encoding memory leak (#4889)
+
+* fix aia encoding memory leak
+
+* don't return anything from the prealloc func
+---
+ .../hazmat/backends/openssl/encode_asn1.py    | 27 +++++----
+ tests/hazmat/backends/test_openssl_memleak.py | 60 +++++++++++++++++++
+ 2 files changed, 75 insertions(+), 12 deletions(-)
+
+diff --git a/src/cryptography/hazmat/backends/openssl/encode_asn1.py b/src/cryptography/hazmat/backends/openssl/encode_asn1.py
+index 61cfd14de0..a774daa788 100644
+--- a/src/cryptography/hazmat/backends/openssl/encode_asn1.py
++++ b/src/cryptography/hazmat/backends/openssl/encode_asn1.py
+@@ -345,16 +345,22 @@ def _encode_authority_information_access(backend, authority_info_access):
+     aia = backend._lib.sk_ACCESS_DESCRIPTION_new_null()
+     backend.openssl_assert(aia != backend._ffi.NULL)
+     aia = backend._ffi.gc(
+-        aia, backend._lib.sk_ACCESS_DESCRIPTION_free
++        aia,
++        lambda x: backend._lib.sk_ACCESS_DESCRIPTION_pop_free(
++            x, backend._ffi.addressof(
++                backend._lib._original_lib, "ACCESS_DESCRIPTION_free"
++            )
++        )
+     )
+     for access_description in authority_info_access:
+         ad = backend._lib.ACCESS_DESCRIPTION_new()
+         method = _txt2obj(
+             backend, access_description.access_method.dotted_string
+         )
+-        gn = _encode_general_name(backend, access_description.access_location)
++        _encode_general_name_preallocated(
++            backend, access_description.access_location, ad.location
++        )
+         ad.method = method
+-        ad.location = gn
+         res = backend._lib.sk_ACCESS_DESCRIPTION_push(aia, ad)
+         backend.openssl_assert(res >= 1)
+ 
+@@ -385,8 +391,13 @@ def _encode_subject_key_identifier(backend, ski):
+ 
+ 
+ def _encode_general_name(backend, name):
++    gn = backend._lib.GENERAL_NAME_new()
++    _encode_general_name_preallocated(backend, name, gn)
++    return gn
++
++
++def _encode_general_name_preallocated(backend, name, gn):
+     if isinstance(name, x509.DNSName):
+-        gn = backend._lib.GENERAL_NAME_new()
+         backend.openssl_assert(gn != backend._ffi.NULL)
+         gn.type = backend._lib.GEN_DNS
+ 
+@@ -400,7 +411,6 @@ def _encode_general_name(backend, name):
+         backend.openssl_assert(res == 1)
+         gn.d.dNSName = ia5
+     elif isinstance(name, x509.RegisteredID):
+-        gn = backend._lib.GENERAL_NAME_new()
+         backend.openssl_assert(gn != backend._ffi.NULL)
+         gn.type = backend._lib.GEN_RID
+         obj = backend._lib.OBJ_txt2obj(
+@@ -409,13 +419,11 @@ def _encode_general_name(backend, name):
+         backend.openssl_assert(obj != backend._ffi.NULL)
+         gn.d.registeredID = obj
+     elif isinstance(name, x509.DirectoryName):
+-        gn = backend._lib.GENERAL_NAME_new()
+         backend.openssl_assert(gn != backend._ffi.NULL)
+         dir_name = _encode_name(backend, name.value)
+         gn.type = backend._lib.GEN_DIRNAME
+         gn.d.directoryName = dir_name
+     elif isinstance(name, x509.IPAddress):
+-        gn = backend._lib.GENERAL_NAME_new()
+         backend.openssl_assert(gn != backend._ffi.NULL)
+         if isinstance(name.value, ipaddress.IPv4Network):
+             packed = (
+@@ -433,7 +441,6 @@ def _encode_general_name(backend, name):
+         gn.type = backend._lib.GEN_IPADD
+         gn.d.iPAddress = ipaddr
+     elif isinstance(name, x509.OtherName):
+-        gn = backend._lib.GENERAL_NAME_new()
+         backend.openssl_assert(gn != backend._ffi.NULL)
+         other_name = backend._lib.OTHERNAME_new()
+         backend.openssl_assert(other_name != backend._ffi.NULL)
+@@ -456,7 +463,6 @@ def _encode_general_name(backend, name):
+         gn.type = backend._lib.GEN_OTHERNAME
+         gn.d.otherName = other_name
+     elif isinstance(name, x509.RFC822Name):
+-        gn = backend._lib.GENERAL_NAME_new()
+         backend.openssl_assert(gn != backend._ffi.NULL)
+         # ia5strings are supposed to be ITU T.50 but to allow round-tripping
+         # of broken certs that encode utf8 we'll encode utf8 here too.
+@@ -465,7 +471,6 @@ def _encode_general_name(backend, name):
+         gn.type = backend._lib.GEN_EMAIL
+         gn.d.rfc822Name = asn1_str
+     elif isinstance(name, x509.UniformResourceIdentifier):
+-        gn = backend._lib.GENERAL_NAME_new()
+         backend.openssl_assert(gn != backend._ffi.NULL)
+         # ia5strings are supposed to be ITU T.50 but to allow round-tripping
+         # of broken certs that encode utf8 we'll encode utf8 here too.
+@@ -478,8 +483,6 @@ def _encode_general_name(backend, name):
+             "{} is an unknown GeneralName type".format(name)
+         )
+ 
+-    return gn
+-
+ 
+ def _encode_extended_key_usage(backend, extended_key_usage):
+     eku = backend._lib.sk_ASN1_OBJECT_new_null()
+diff --git a/tests/hazmat/backends/test_openssl_memleak.py b/tests/hazmat/backends/test_openssl_memleak.py
+index f9ae1c46b9..935ea3dfe3 100644
+--- a/tests/hazmat/backends/test_openssl_memleak.py
++++ b/tests/hazmat/backends/test_openssl_memleak.py
+@@ -389,3 +389,63 @@ def func():
+                 x509.IssuingDistributionPoint
+             )
+         """))
++
++    def test_create_certificate_with_extensions(self):
++        assert_no_memory_leaks(textwrap.dedent("""
++        def func():
++            import datetime
++
++            from cryptography import x509
++            from cryptography.hazmat.backends.openssl import backend
++            from cryptography.hazmat.primitives import hashes
++            from cryptography.hazmat.primitives.asymmetric import ec
++            from cryptography.x509.oid import (
++                AuthorityInformationAccessOID, ExtendedKeyUsageOID, NameOID
++            )
++
++            private_key = ec.generate_private_key(ec.SECP256R1(), backend)
++
++            not_valid_before = datetime.datetime.now()
++            not_valid_after = not_valid_before + datetime.timedelta(days=365)
++
++            aia = x509.AuthorityInformationAccess([
++                x509.AccessDescription(
++                    AuthorityInformationAccessOID.OCSP,
++                    x509.UniformResourceIdentifier(u"http://ocsp.domain.com";)
++                ),
++                x509.AccessDescription(
++                    AuthorityInformationAccessOID.CA_ISSUERS,
++                    x509.UniformResourceIdentifier(u"http://domain.com/ca.crt";)
++                )
++            ])
++            sans = [u'*.example.org', u'foobar.example.net']
++            san = x509.SubjectAlternativeName(list(map(x509.DNSName, sans)))
++
++            ski = x509.SubjectKeyIdentifier.from_public_key(
++                private_key.public_key()
++            )
++            eku = x509.ExtendedKeyUsage([
++                ExtendedKeyUsageOID.CLIENT_AUTH,
++                ExtendedKeyUsageOID.SERVER_AUTH,
++                ExtendedKeyUsageOID.CODE_SIGNING,
++            ])
++
++            builder = x509.CertificateBuilder().serial_number(
++                777
++            ).issuer_name(x509.Name([
++                x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
++            ])).subject_name(x509.Name([
++                x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
++            ])).public_key(
++                private_key.public_key()
++            ).add_extension(
++                aia, critical=False
++            ).not_valid_before(
++                not_valid_before
++            ).not_valid_after(
++                not_valid_after
++            )
++
++            cert = builder.sign(private_key, hashes.SHA256(), backend)
++            cert.extensions
++        """))
diff -Nru python-cryptography-2.6.1/debian/patches/series python-cryptography-2.6.1/debian/patches/series
--- python-cryptography-2.6.1/debian/patches/series	2019-09-24 20:38:45.000000000 +0200
+++ python-cryptography-2.6.1/debian/patches/series	2019-10-18 16:08:51.000000000 +0200
@@ -1,3 +1,5 @@
 update-our-test-to-be-more-robust-wrt-some-changes-f.patch
 use-a-random-key-for-these-tests-4887.patch
 tests-Skip-test_load_ecdsa_no_named_curve.patch
+aia-memleak-1.patch
+aia-memleak-2.patch

--- End Message ---
--- Begin Message ---
Package: release.debian.org
Version: 10.2

Hi,

The fixes referenced by these bugs were included in today's 10.2 stable
point release.

Regards,

Adam

--- End Message ---

Reply to: