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