Commits

Armin Rigo  committed 35cba9c

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.

  • Participants
  • Parent commits 6efbea3

Comments (0)

Files changed (1)

File pypy/module/_hashlib/interp_hashlib.py

         + 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')
         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')
 
     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."