Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r59514:35cba9cbed62
Date: 2012-12-19 21:11 +0100
http://bitbucket.org/pypy/pypy/changeset/35cba9cbed62/

Log:    Fix leak: calling .copy() would initialize a ctx and then overwrite
        it with EVP_MD_CTX_copy(). The latter must be called with a non-
        initialized ctx.

diff --git a/pypy/module/_hashlib/interp_hashlib.py 
b/pypy/module/_hashlib/interp_hashlib.py
--- a/pypy/module/_hashlib/interp_hashlib.py
+++ b/pypy/module/_hashlib/interp_hashlib.py
@@ -20,9 +20,10 @@
         + rffi.sizeof(ropenssl.EVP_MD) * 2 + 208
 
 class W_Hash(Wrappable):
-    ctx = lltype.nullptr(ropenssl.EVP_MD_CTX.TO)
+    NULL_CTX = lltype.nullptr(ropenssl.EVP_MD_CTX.TO)
+    ctx = NULL_CTX
 
-    def __init__(self, space, name):
+    def __init__(self, space, name, copy_from=NULL_CTX):
         self.name = name
         digest_type = self.digest_type_by_name(space)
         self.digest_size = rffi.getintfield(digest_type, 'c_md_size')
@@ -35,7 +36,10 @@
         ctx = lltype.malloc(ropenssl.EVP_MD_CTX.TO, flavor='raw')
         rgc.add_memory_pressure(HASH_MALLOC_SIZE + self.digest_size)
         try:
-            ropenssl.EVP_DigestInit(ctx, digest_type)
+            if copy_from:
+                ropenssl.EVP_MD_CTX_copy(ctx, copy_from)
+            else:
+                ropenssl.EVP_DigestInit(ctx, digest_type)
             self.ctx = ctx
         except:
             lltype.free(ctx, flavor='raw')
@@ -67,10 +71,8 @@
 
     def copy(self, space):
         "Return a copy of the hash object."
-        w_hash = W_Hash(space, self.name)
         with self.lock:
-            ropenssl.EVP_MD_CTX_copy(w_hash.ctx, self.ctx)
-        return w_hash
+            return W_Hash(space, self.name, copy_from=self.ctx)
 
     def digest(self, space):
         "Return the digest value as a string of binary data."
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to