From e7a0179ed39f707a42b8c15157bdb3f0aa45dd13 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Thu, 1 Dec 2011 15:25:31 -0800 Subject: [PATCH] checksum.py: detect PyPy crashes in hashlib Use a fork to try and PyPy by digesting random data with hashlib functions. It doesn't look like a bug has been reported upstream for this yet, so it may or may not be reproducible by others. Anyway, this allows me to avoid crashing the main PyPy process until I find a real fix. --- pym/portage/checksum.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/pym/portage/checksum.py b/pym/portage/checksum.py index f10fc4d55..77035b600 100644 --- a/pym/portage/checksum.py +++ b/pym/portage/checksum.py @@ -9,6 +9,7 @@ from portage import os from portage import _encodings from portage import _unicode_encode import errno +import platform import stat import tempfile @@ -61,6 +62,28 @@ class _generate_hash_function(object): return (checksum.hexdigest(), size) +_test_hash_func = False +if platform.python_implementation() == 'PyPy': + def _test_hash_func(constructor): + """ + Test for PyPy crashes observed with hashlib's ripemd160 and whirlpool + functions executed under pypy-1.7 with Python 2.7.1: + *** glibc detected *** pypy-c1.7: free(): invalid next size (fast): 0x0b963a38 *** + *** glibc detected *** pypy-c1.7: free(): corrupted unsorted chunks: 0x09c490b0 *** + """ + import random + pid = os.fork() + if pid == 0: + data = list(b'abcdefg') + for i in range(10): + checksum = constructor() + random.shuffle(data) + checksum.update(b''.join(data)) + checksum.hexdigest() + os._exit(os.EX_OK) + pid, status = os.waitpid(pid, 0) + return os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK + # Define hash functions, try to use the best module available. Later definitions # override earlier ones @@ -129,6 +152,12 @@ try: except ValueError: pass else: + if _test_hash_func and \ + not _test_hash_func(functools.partial(hashlib.new, hash_name)): + portage.util.writemsg("\n!!! hash function appears to " + "crash python: %s from %s\n" % + (hash_name, "hashlib"), noiselevel=-1) + continue globals()['%shash' % local_name] = \ _generate_hash_function(local_name.upper(), \ functools.partial(hashlib.new, hash_name), \ -- 2.26.2