From 3157d6d7b742d28dc321e4d68342809645a93207 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 15 Dec 2011 22:24:19 -0500 Subject: [PATCH] handle errors when constructing lists in the Python bindings - Various functions in the Python bindings construct lists of objects, but assume that all calls succeed. Each of these could segfault under low-memory conditions: if the PyList_New() call fails, PyList_Append(NULL, item ) will segfault. Similarly, although Py_List_Append(list, NULL) is safe, Py_DECREF(NULL) will segfault. Signed-off-by: Ales Kozumplik --- python/header-py.c | 15 +++++++++++++-- python/rpmps-py.c | 16 ++++++++++++++-- python/rpmtd-py.c | 7 +++++++ python/spec-py.c | 27 ++++++++++++++++++++++++--- 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/python/header-py.c b/python/header-py.c index cef457b..9e245aa 100644 --- a/python/header-py.c +++ b/python/header-py.c @@ -132,12 +132,23 @@ struct hdrObject_s { static PyObject * hdrKeyList(hdrObject * s) { - PyObject * keys = PyList_New(0); - HeaderIterator hi = headerInitIterator(s->h); + PyObject * keys; + HeaderIterator hi; rpmTagVal tag; + keys = PyList_New(0); + if (!keys) { + return NULL; + } + + hi = headerInitIterator(s->h); while ((tag = headerNextTag(hi)) != RPMTAG_NOT_FOUND) { PyObject *to = PyInt_FromLong(tag); + if (!to) { + headerFreeIterator(hi); + Py_DECREF(keys); + return NULL; + } PyList_Append(keys, to); Py_DECREF(to); } diff --git a/python/rpmps-py.c b/python/rpmps-py.c index 8b178fa..bdc899a 100644 --- a/python/rpmps-py.c +++ b/python/rpmps-py.c @@ -125,12 +125,24 @@ PyObject *rpmprob_Wrap(PyTypeObject *subtype, rpmProblem prob) PyObject *rpmps_AsList(rpmps ps) { - PyObject *problems = PyList_New(0); - rpmpsi psi = rpmpsInitIterator(ps); + PyObject *problems; + rpmpsi psi; rpmProblem prob; + problems = PyList_New(0); + if (!problems) { + return NULL; + } + + psi = rpmpsInitIterator(ps); + while ((prob = rpmpsiNext(psi))) { PyObject *pyprob = rpmprob_Wrap(&rpmProblem_Type, prob); + if (!pyprob) { + Py_DECREF(problems); + rpmpsFreeIterator(psi); + return NULL; + } PyList_Append(problems, pyprob); Py_DECREF(pyprob); } diff --git a/python/rpmtd-py.c b/python/rpmtd-py.c index 8232127..026f6c7 100644 --- a/python/rpmtd-py.c +++ b/python/rpmtd-py.c @@ -44,8 +44,15 @@ PyObject *rpmtd_AsPyobj(rpmtd td) if (array) { res = PyList_New(0); + if (!res) { + return NULL; + } while (rpmtdNext(td) >= 0) { PyObject *item = rpmtd_ItemAsPyobj(td, tclass); + if (!item) { + Py_DECREF(res); + return NULL; + } PyList_Append(res, item); Py_DECREF(item); } diff --git a/python/spec-py.c b/python/spec-py.c index 49b9e1d..1850a50 100644 --- a/python/spec-py.c +++ b/python/spec-py.c @@ -151,15 +151,24 @@ static PyObject * spec_get_clean(specObject * s, void *closure) static PyObject * spec_get_sources(specObject *s, void *closure) { - PyObject *sourceList = PyList_New(0); + PyObject *sourceList; rpmSpecSrc source; + sourceList = PyList_New(0); + if (!sourceList) { + return NULL; + } + rpmSpecSrcIter iter = rpmSpecSrcIterInit(s->spec); while ((source = rpmSpecSrcIterNext(iter)) != NULL) { PyObject *srcUrl = Py_BuildValue("(sii)", rpmSpecSrcFilename(source, 1), rpmSpecSrcNum(source), rpmSpecSrcFlags(source)); + if (!srcUrl) { + Py_DECREF(sourceList); + return NULL; + } PyList_Append(sourceList, srcUrl); Py_DECREF(srcUrl); } @@ -172,11 +181,23 @@ static PyObject * spec_get_sources(specObject *s, void *closure) static PyObject * spec_get_packages(specObject *s, void *closure) { rpmSpecPkg pkg; - PyObject *pkgList = PyList_New(0); - rpmSpecPkgIter iter = rpmSpecPkgIterInit(s->spec); + PyObject *pkgList; + rpmSpecPkgIter iter; + + pkgList = PyList_New(0); + if (!pkgList) { + return NULL; + } + + iter = rpmSpecPkgIterInit(s->spec); while ((pkg = rpmSpecPkgIterNext(iter)) != NULL) { PyObject *po = specPkg_Wrap(&specPkg_Type, pkg); + if (!po) { + rpmSpecPkgIterFree(iter); + Py_DECREF(pkgList); + return NULL; + } PyList_Append(pkgList, po); Py_DECREF(po); } -- 2.7.4