Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r80568:3b433cf781c7
Date: 2015-11-06 18:54 +0100
http://bitbucket.org/pypy/pypy/changeset/3b433cf781c7/

Log:    Issue #2183: leak fix, untested so far

diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py
--- a/pypy/module/_ssl/interp_ssl.py
+++ b/pypy/module/_ssl/interp_ssl.py
@@ -852,55 +852,58 @@
                     names = rffi.cast(GENERAL_NAMES, method[0].c_d2i(
                         null, p_ptr, length))
 
-            for j in range(libssl_sk_GENERAL_NAME_num(names)):
-                # Get a rendering of each name in the set of names
+            try:
+                for j in range(libssl_sk_GENERAL_NAME_num(names)):
+                    # Get a rendering of each name in the set of names
 
-                name = libssl_sk_GENERAL_NAME_value(names, j)
-                gntype = intmask(name.c_type)
-                if gntype == GEN_DIRNAME:
-                    # we special-case DirName as a tuple of tuples of
-                    # attributes
-                    dirname = libssl_pypy_GENERAL_NAME_dirn(name)
-                    w_t = space.newtuple([
-                        space.wrap("DirName"),
-                        _create_tuple_for_X509_NAME(space, dirname)
-                        ])
-                elif gntype in (GEN_EMAIL, GEN_DNS, GEN_URI):
-                    # GENERAL_NAME_print() doesn't handle NULL bytes in
-                    # ASN1_string correctly, CVE-2013-4238
-                    if gntype == GEN_EMAIL:
-                        v = space.wrap("email")
-                    elif gntype == GEN_DNS:
-                        v = space.wrap("DNS")
-                    elif gntype == GEN_URI:
-                        v = space.wrap("URI")
+                    name = libssl_sk_GENERAL_NAME_value(names, j)
+                    gntype = intmask(name.c_type)
+                    if gntype == GEN_DIRNAME:
+                        # we special-case DirName as a tuple of tuples of
+                        # attributes
+                        dirname = libssl_pypy_GENERAL_NAME_dirn(name)
+                        w_t = space.newtuple([
+                            space.wrap("DirName"),
+                            _create_tuple_for_X509_NAME(space, dirname)
+                            ])
+                    elif gntype in (GEN_EMAIL, GEN_DNS, GEN_URI):
+                        # GENERAL_NAME_print() doesn't handle NULL bytes in
+                        # ASN1_string correctly, CVE-2013-4238
+                        if gntype == GEN_EMAIL:
+                            v = space.wrap("email")
+                        elif gntype == GEN_DNS:
+                            v = space.wrap("DNS")
+                        elif gntype == GEN_URI:
+                            v = space.wrap("URI")
+                        else:
+                            assert False
+                        as_ = libssl_pypy_GENERAL_NAME_dirn(name)
+                        as_ = rffi.cast(ASN1_STRING, as_)
+                        buf = libssl_ASN1_STRING_data(as_)
+                        length = libssl_ASN1_STRING_length(as_)
+                        w_t = space.newtuple([
+                            v, space.wrap(rffi.charpsize2str(buf, length))])
                     else:
-                        assert False
-                    as_ = libssl_pypy_GENERAL_NAME_dirn(name)
-                    as_ = rffi.cast(ASN1_STRING, as_)
-                    buf = libssl_ASN1_STRING_data(as_)
-                    length = libssl_ASN1_STRING_length(as_)
-                    w_t = space.newtuple([
-                        v, space.wrap(rffi.charpsize2str(buf, length))])
-                else:
-                    # for everything else, we use the OpenSSL print form
-                    if gntype not in (GEN_OTHERNAME, GEN_X400, GEN_EDIPARTY,
-                                      GEN_IPADD, GEN_RID):
-                        space.warn(space.wrap("Unknown general name type"),
-                                   space.w_RuntimeWarning)
-                    libssl_BIO_reset(biobuf)
-                    libssl_GENERAL_NAME_print(biobuf, name)
-                    with lltype.scoped_alloc(rffi.CCHARP.TO, 2048) as buf:
-                        length = libssl_BIO_gets(biobuf, buf, 2047)
-                        if length < 0:
-                            raise _ssl_seterror(space, None, 0)
+                        # for everything else, we use the OpenSSL print form
+                        if gntype not in (GEN_OTHERNAME, GEN_X400, 
GEN_EDIPARTY,
+                                          GEN_IPADD, GEN_RID):
+                            space.warn(space.wrap("Unknown general name type"),
+                                       space.w_RuntimeWarning)
+                        libssl_BIO_reset(biobuf)
+                        libssl_GENERAL_NAME_print(biobuf, name)
+                        with lltype.scoped_alloc(rffi.CCHARP.TO, 2048) as buf:
+                            length = libssl_BIO_gets(biobuf, buf, 2047)
+                            if length < 0:
+                                raise _ssl_seterror(space, None, 0)
 
-                        v = rffi.charpsize2str(buf, length)
-                    v1, v2 = v.split(':', 1)
-                    w_t = space.newtuple([space.wrap(v1),
-                                          space.wrap(v2)])
+                            v = rffi.charpsize2str(buf, length)
+                        v1, v2 = v.split(':', 1)
+                        w_t = space.newtuple([space.wrap(v1),
+                                              space.wrap(v2)])
 
-                alt_names_w.append(w_t)
+                    alt_names_w.append(w_t)
+            finally:
+                libssl_pypy_GENERAL_NAME_pop_free(names)
     finally:
         libssl_BIO_free(biobuf)
 
diff --git a/rpython/rlib/ropenssl.py b/rpython/rlib/ropenssl.py
--- a/rpython/rlib/ropenssl.py
+++ b/rpython/rlib/ropenssl.py
@@ -56,6 +56,7 @@
         # So we replace an attribute access with a macro call.
         '#define pypy_GENERAL_NAME_dirn(name) (name->d.dirn)',
         '#define pypy_GENERAL_NAME_uri(name) 
(name->d.uniformResourceIdentifier)',
+        '#define pypy_GENERAL_NAME_pop_free(names) 
(sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free))',
         '#define pypy_X509_OBJECT_data_x509(obj) (obj->data.x509)',
         '#define pypy_DIST_POINT_fullname(obj) 
(obj->distpoint->name.fullname)',
     ],
@@ -439,6 +440,8 @@
              macro=True)
 ssl_external('sk_GENERAL_NAME_value', [GENERAL_NAMES, rffi.INT], GENERAL_NAME,
              macro=True)
+ssl_external('pypy_GENERAL_NAME_pop_free', [GENERAL_NAMES], lltype.Void,
+             macro=True)
 ssl_external('sk_X509_OBJECT_num', [stack_st_X509_OBJECT], rffi.INT,
              macro=True)
 ssl_external('sk_X509_OBJECT_value', [stack_st_X509_OBJECT, rffi.INT],
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to