From bda7f75437f709dd811a50f4a942ae07cc4057d2 Mon Sep 17 00:00:00 2001 From: Paul Howarth Date: Feb 18 2012 20:28:45 +0000 Subject: Fix issues found by static analysis (#790584) --- diff --git a/0001-Fix-segfaults-reference-leaks-in-error-handling.patch b/0001-Fix-segfaults-reference-leaks-in-error-handling.patch new file mode 100644 index 0000000..548840f --- /dev/null +++ b/0001-Fix-segfaults-reference-leaks-in-error-handling.patch @@ -0,0 +1,202 @@ +From 34d79c1c99b0baf3357507245e0f0419297ea4e2 Mon Sep 17 00:00:00 2001 +From: "Dwayne C. Litzenberger" +Date: Sat, 18 Feb 2012 12:35:23 -0500 +Subject: [PATCH 1/3] Fix segfaults & reference leaks in error-handling + +These bugs are likely only triggered during out-of-memory conditions. The bug +report is at: + + https://bugs.launchpad.net/pycrypto/+bug/934294 + +These were found by Dave Malcolm's experimental static analysis tool: + + http://fedorapeople.org/~dmalcolm/gcc-python-plugin/2012-02-14/python-crypto-2.5-1.fc17/ + +See also: + + https://fedorahosted.org/gcc-python-plugin/ + http://gcc-python-plugin.readthedocs.org/en/latest/cpychecker.html +--- + src/_fastmath.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++-------- + 1 files changed, 58 insertions(+), 10 deletions(-) + +diff --git a/src/_fastmath.c b/src/_fastmath.c +index 6af1f05..c0f8c4e 100644 +--- a/src/_fastmath.c ++++ b/src/_fastmath.c +@@ -466,6 +466,8 @@ dsaKey_new (PyObject * self, PyObject * args) + return NULL; + + key = PyObject_New (dsaKey, &dsaKeyType); ++ if (key == NULL) ++ return NULL; + mpz_init (key->y); + mpz_init (key->g); + mpz_init (key->p); +@@ -552,7 +554,7 @@ dsaKey_getattr (dsaKey * key, char *attr) + static PyObject * + dsaKey__sign (dsaKey * key, PyObject * args) + { +- PyObject *lm, *lk, *lr, *ls; ++ PyObject *lm, *lk, *lr, *ls, *retval; + mpz_t m, k, r, s; + int result; + if (!PyArg_ParseTuple (args, "O!O!", &PyLong_Type, &lm, +@@ -574,11 +576,19 @@ dsaKey__sign (dsaKey * key, PyObject * args) + } + lr = mpzToLongObj (r); + ls = mpzToLongObj (s); ++ if (lr == NULL || ls == NULL) goto errout; + mpz_clear (m); + mpz_clear (k); + mpz_clear (r); + mpz_clear (s); +- return Py_BuildValue ("(NN)", lr, ls); ++ retval = Py_BuildValue ("(NN)", lr, ls); ++ if (retval == NULL) goto errout; ++ return retval; ++ ++errout: ++ Py_XDECREF(lr); ++ Py_XDECREF(ls); ++ return NULL; + } + + static PyObject * +@@ -703,6 +713,8 @@ rsaKey_new (PyObject * self, PyObject * args) + return NULL; + + key = PyObject_New (rsaKey, &rsaKeyType); ++ if (key == NULL) ++ return NULL; + mpz_init (key->n); + mpz_init (key->e); + mpz_init (key->d); +@@ -838,7 +850,7 @@ rsaKey_getattr (rsaKey * key, char *attr) + static PyObject * + rsaKey__encrypt (rsaKey * key, PyObject * args) + { +- PyObject *l, *r; ++ PyObject *l, *r, *retval; + mpz_t v; + int result; + if (!PyArg_ParseTuple (args, "O!", &PyLong_Type, &l)) +@@ -854,14 +866,20 @@ rsaKey__encrypt (rsaKey * key, PyObject * args) + return NULL; + } + r = (PyObject *) mpzToLongObj (v); ++ if (r == NULL) return NULL; + mpz_clear (v); +- return Py_BuildValue ("N", r); ++ retval = Py_BuildValue ("N", r); ++ if (retval == NULL) { ++ Py_DECREF(r); ++ return NULL; ++ } ++ return retval; + } + + static PyObject * + rsaKey__decrypt (rsaKey * key, PyObject * args) + { +- PyObject *l, *r; ++ PyObject *l, *r, *retval; + mpz_t v; + int result; + if (!PyArg_ParseTuple (args, "O!", &PyLong_Type, &l)) +@@ -884,8 +902,14 @@ rsaKey__decrypt (rsaKey * key, PyObject * args) + return NULL; + } + r = mpzToLongObj (v); ++ if (r == NULL) return NULL; + mpz_clear (v); +- return Py_BuildValue ("N", r); ++ retval = Py_BuildValue ("N", r); ++ if (retval == NULL) { ++ Py_DECREF(r); ++ return NULL; ++ } ++ return retval; + } + + static PyObject * +@@ -916,7 +940,7 @@ rsaKey__verify (rsaKey * key, PyObject * args) + static PyObject * + rsaKey__blind (rsaKey * key, PyObject * args) + { +- PyObject *l, *lblind, *r; ++ PyObject *l, *lblind, *r, *retval; + mpz_t v, vblind; + int result; + if (!PyArg_ParseTuple (args, "O!O!", &PyLong_Type, &l, +@@ -940,15 +964,22 @@ rsaKey__blind (rsaKey * key, PyObject * args) + return NULL; + } + r = (PyObject *) mpzToLongObj (v); ++ if (r == NULL) ++ return NULL; + mpz_clear (v); + mpz_clear (vblind); +- return Py_BuildValue ("N", r); ++ retval = Py_BuildValue ("N", r); ++ if (retval == NULL) { ++ Py_DECREF(r); ++ return NULL; ++ } ++ return retval; + } + + static PyObject * + rsaKey__unblind (rsaKey * key, PyObject * args) + { +- PyObject *l, *lblind, *r; ++ PyObject *l, *lblind, *r, *retval; + mpz_t v, vblind; + int result; + if (!PyArg_ParseTuple (args, "O!O!", &PyLong_Type, &l, +@@ -977,9 +1008,15 @@ rsaKey__unblind (rsaKey * key, PyObject * args) + return NULL; + } + r = (PyObject *) mpzToLongObj (v); ++ if (r == NULL) return NULL; + mpz_clear (v); + mpz_clear (vblind); +- return Py_BuildValue ("N", r); ++ retval = Py_BuildValue ("N", r); ++ if (retval == NULL) { ++ Py_DECREF(r); ++ return NULL; ++ } ++ return retval; + } + + static PyObject * +@@ -1153,7 +1190,15 @@ getRandomInteger (mpz_t n, unsigned long int bits, PyObject *randfunc_) + } + + arglist = Py_BuildValue ("(l)", (long int)bytes); ++ if (arglist == NULL) { ++ return_val = 0; ++ goto cleanup; ++ } + rand_bytes = PyObject_CallObject (randfunc, arglist); ++ if (rand_bytes == NULL) { ++ return_val = 0; ++ goto cleanup; ++ } + Py_DECREF (arglist); + if (!PyBytes_Check (rand_bytes)) + { +@@ -1650,6 +1695,9 @@ init_fastmath (void) + #endif + _fastmath_dict = PyModule_GetDict (_fastmath_module); + fastmathError = PyErr_NewException ("_fastmath.error", NULL, NULL); ++#ifdef IS_PY3K ++ if (fastmathError == NULL) return NULL; ++#endif + PyDict_SetItemString (_fastmath_dict, "error", fastmathError); + + PyModule_AddIntConstant(_fastmath_module, "HAVE_DECL_MPZ_POWM_SEC", HAVE_DECL_MPZ_POWM_SEC); +-- +1.7.7.6 + diff --git a/0002-Fix-typo.patch b/0002-Fix-typo.patch new file mode 100644 index 0000000..fb0e4a3 --- /dev/null +++ b/0002-Fix-typo.patch @@ -0,0 +1,25 @@ +From a6ddd108cf8e70c4037065143f968e994f5ef581 Mon Sep 17 00:00:00 2001 +From: "Dwayne C. Litzenberger" +Date: Sat, 18 Feb 2012 12:42:23 -0500 +Subject: [PATCH 2/3] Fix typo + +--- + src/_fastmath.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/src/_fastmath.c b/src/_fastmath.c +index c0f8c4e..8c1a517 100644 +--- a/src/_fastmath.c ++++ b/src/_fastmath.c +@@ -1139,7 +1139,7 @@ getRNG (void) + if (!PyCallable_Check (new_func)) + { + PyErr_SetString (PyExc_RuntimeError, +- "Cryptor.Random.new is not callable."); ++ "Crypto.Random.new is not callable."); + return NULL; + } + rng = PyObject_CallObject (new_func, NULL); +-- +1.7.7.6 + diff --git a/0003-Fix-segfault-if-Crypto.Random.new-is-missing.patch b/0003-Fix-segfault-if-Crypto.Random.new-is-missing.patch new file mode 100644 index 0000000..5c8641b --- /dev/null +++ b/0003-Fix-segfault-if-Crypto.Random.new-is-missing.patch @@ -0,0 +1,33 @@ +From 4b3c25f4b872c288ace179c68cebc46cce5039aa Mon Sep 17 00:00:00 2001 +From: "Dwayne C. Litzenberger" +Date: Sat, 18 Feb 2012 12:51:11 -0500 +Subject: [PATCH 3/3] Fix segfault if Crypto.Random.new is missing for some + reason. + +This should never happen, but we're already checking that Crypto.Random.new is +callable, so we might as well also check that Crypto.Random.new exists. Also, +fixing this should silence an (arguably false-positive) error emitted by +cpychecker (a static analysis tool used by the Fedora project). +--- + src/_fastmath.c | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +diff --git a/src/_fastmath.c b/src/_fastmath.c +index 8c1a517..4b5dede 100644 +--- a/src/_fastmath.c ++++ b/src/_fastmath.c +@@ -1136,6 +1136,11 @@ getRNG (void) + module_dict = PyModule_GetDict (module); + Py_DECREF (module); + new_func = PyDict_GetItemString (module_dict, "new"); ++ if (new_func == NULL) { ++ PyErr_SetString (PyExc_RuntimeError, ++ "Crypto.Random.new is missing."); ++ return NULL; ++ } + if (!PyCallable_Check (new_func)) + { + PyErr_SetString (PyExc_RuntimeError, +-- +1.7.7.6 + diff --git a/python-crypto.spec b/python-crypto.spec index 1143f5c..80106c5 100644 --- a/python-crypto.spec +++ b/python-crypto.spec @@ -7,7 +7,7 @@ Summary: Cryptography library for Python Name: python-crypto Version: 2.5 -Release: 1%{?dist} +Release: 2%{?dist} # Mostly Public Domain apart from parts of HMAC.py and setup.py, which are Python License: Public Domain and Python Group: Development/Libraries @@ -15,6 +15,9 @@ URL: http://www.pycrypto.org/ Source0: http://ftp.dlitz.net/pub/dlitz/crypto/pycrypto/pycrypto-%{version}.tar.gz Patch0: python-crypto-2.4-optflags.patch Patch1: python-crypto-2.4-fix-pubkey-size-divisions.patch +Patch2: 0001-Fix-segfaults-reference-leaks-in-error-handling.patch +Patch3: 0002-Fix-typo.patch +Patch4: 0003-Fix-segfault-if-Crypto.Random.new-is-missing.patch Provides: pycrypto = %{version}-%{release} BuildRequires: python2-devel >= 2.2, gmp-devel >= 4.1 %if %{with_python3} @@ -55,6 +58,12 @@ This is the Python 3 build of the package. # Fix divisions within benchmarking suite: %patch1 -p1 +# Upstream fixes for issues found by Dave Malcolm's +# experimental static analysis tool (#790584) +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 + # Prepare python3 build (setup.py doesn't run 2to3 on pct-speedtest.py) %if %{with_python3} cp -a . %{py3dir} @@ -123,6 +132,10 @@ rm -rf %{buildroot} %endif %changelog +* Sat Feb 18 2012 Paul Howarth - 2.5-2 +- Add upstream fixes for issues found by Dave Malcolm's experimental static + analysis tool (#790584) + * Mon Jan 16 2012 Paul Howarth - 2.5-1 - Update to 2.5 - Added PKCS#1 encryption schemes (v1.5 and OAEP); we now have a decent,