Blob Blame History Raw
From 34d79c1c99b0baf3357507245e0f0419297ea4e2 Mon Sep 17 00:00:00 2001
From: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
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