diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2016-12-19 06:05:39 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2016-12-19 06:05:39 (GMT) |
commit | 879199ba11947d9765b06806df54566fde75d498 (patch) | |
tree | 75d0d1a20cfcf0cc6f915fd58633e5d420dc4a9c /Modules/resource.c | |
parent | cd259bfd5acd7927caaa5a61d4dbe4894389f0cf (diff) | |
parent | b94eef2ae3737b1f03452a30d5c96640c838dc46 (diff) | |
download | cpython-879199ba11947d9765b06806df54566fde75d498.zip cpython-879199ba11947d9765b06806df54566fde75d498.tar.gz cpython-879199ba11947d9765b06806df54566fde75d498.tar.bz2 |
Issue #20191: Fixed a crash in resource.prlimit() when pass a sequence that
doesn't own its elements as limits.
Diffstat (limited to 'Modules/resource.c')
-rw-r--r-- | Modules/resource.c | 64 |
1 files changed, 31 insertions, 33 deletions
diff --git a/Modules/resource.c b/Modules/resource.c index 6702b7a..113ad5c 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -107,29 +107,46 @@ resource_getrusage(PyObject *self, PyObject *args) } static int -py2rlimit(PyObject *curobj, PyObject *maxobj, struct rlimit *rl_out) +py2rlimit(PyObject *limits, struct rlimit *rl_out) { + PyObject *curobj, *maxobj; + limits = PySequence_Tuple(limits); + if (!limits) + /* Here limits is a borrowed reference */ + return -1; + + if (PyTuple_GET_SIZE(limits) != 2) { + PyErr_SetString(PyExc_ValueError, + "expected a tuple of 2 integers"); + goto error; + } + curobj = PyTuple_GET_ITEM(limits, 0); + maxobj = PyTuple_GET_ITEM(limits, 1); #if !defined(HAVE_LARGEFILE_SUPPORT) rl_out->rlim_cur = PyLong_AsLong(curobj); if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred()) - return -1; + goto error; rl_out->rlim_max = PyLong_AsLong(maxobj); if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred()) - return -1; + goto error; #else /* The limits are probably bigger than a long */ rl_out->rlim_cur = PyLong_AsLongLong(curobj); if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred()) - return -1; + goto error; rl_out->rlim_max = PyLong_AsLongLong(maxobj); if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred()) - return -1; + goto error; #endif + Py_DECREF(limits); rl_out->rlim_cur = rl_out->rlim_cur & RLIM_INFINITY; rl_out->rlim_max = rl_out->rlim_max & RLIM_INFINITY; return 0; +error: + Py_DECREF(limits); + return -1; } static PyObject* @@ -170,7 +187,7 @@ resource_setrlimit(PyObject *self, PyObject *args) { struct rlimit rl; int resource; - PyObject *limits, *curobj, *maxobj; + PyObject *limits; if (!PyArg_ParseTuple(args, "iO:setrlimit", &resource, &limits)) return NULL; @@ -181,21 +198,8 @@ resource_setrlimit(PyObject *self, PyObject *args) return NULL; } - limits = PySequence_Tuple(limits); - if (!limits) - /* Here limits is a borrowed reference */ + if (py2rlimit(limits, &rl) < 0) { return NULL; - - if (PyTuple_GET_SIZE(limits) != 2) { - PyErr_SetString(PyExc_ValueError, - "expected a tuple of 2 integers"); - goto error; - } - curobj = PyTuple_GET_ITEM(limits, 0); - maxobj = PyTuple_GET_ITEM(limits, 1); - - if (py2rlimit(curobj, maxobj, &rl) < 0) { - goto error; } if (setrlimit(resource, &rl) == -1) { @@ -207,15 +211,9 @@ resource_setrlimit(PyObject *self, PyObject *args) "not allowed to raise maximum limit"); else PyErr_SetFromErrno(PyExc_OSError); - goto error; + return NULL; } - Py_DECREF(limits); - Py_INCREF(Py_None); - return Py_None; - - error: - Py_DECREF(limits); - return NULL; + Py_RETURN_NONE; } #ifdef HAVE_PRLIMIT @@ -225,10 +223,10 @@ resource_prlimit(PyObject *self, PyObject *args) struct rlimit old_limit, new_limit; int resource, retval; pid_t pid; - PyObject *curobj=NULL, *maxobj=NULL; + PyObject *limits = NULL; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i|(OO):prlimit", - &pid, &resource, &curobj, &maxobj)) + if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i|O:prlimit", + &pid, &resource, &limits)) return NULL; if (resource < 0 || resource >= RLIM_NLIMITS) { @@ -237,8 +235,8 @@ resource_prlimit(PyObject *self, PyObject *args) return NULL; } - if (curobj != NULL) { - if (py2rlimit(curobj, maxobj, &new_limit) < 0) { + if (limits != NULL) { + if (py2rlimit(limits, &new_limit) < 0) { return NULL; } retval = prlimit(pid, resource, &new_limit, &old_limit); |