mirror of https://github.com/python/cpython
bpo-42146: Fix memory leak in subprocess.Popen() in case of uid/gid overflow (GH-22966)
Fix memory leak in subprocess.Popen() in case of uid/gid overflow Also add a test that would catch this leak with `--huntrleaks`. Alas, the test for `extra_groups` also exposes an inconsistency in our error reporting: we use a custom ValueError for `extra_groups`, but propagate OverflowError for `user` and `group`.
This commit is contained in:
parent
e68c67805e
commit
c0590c0033
|
@ -1895,6 +1895,10 @@ class POSIXProcessTestCase(BaseTestCase):
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
subprocess.check_call(ZERO_RETURN_CMD, user=-1)
|
subprocess.check_call(ZERO_RETURN_CMD, user=-1)
|
||||||
|
|
||||||
|
with self.assertRaises(OverflowError):
|
||||||
|
subprocess.check_call(ZERO_RETURN_CMD,
|
||||||
|
cwd=os.curdir, env=os.environ, user=2**64)
|
||||||
|
|
||||||
if pwd is None and name_uid is not None:
|
if pwd is None and name_uid is not None:
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
subprocess.check_call(ZERO_RETURN_CMD, user=name_uid)
|
subprocess.check_call(ZERO_RETURN_CMD, user=name_uid)
|
||||||
|
@ -1938,6 +1942,10 @@ class POSIXProcessTestCase(BaseTestCase):
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
subprocess.check_call(ZERO_RETURN_CMD, group=-1)
|
subprocess.check_call(ZERO_RETURN_CMD, group=-1)
|
||||||
|
|
||||||
|
with self.assertRaises(OverflowError):
|
||||||
|
subprocess.check_call(ZERO_RETURN_CMD,
|
||||||
|
cwd=os.curdir, env=os.environ, group=2**64)
|
||||||
|
|
||||||
if grp is None:
|
if grp is None:
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
subprocess.check_call(ZERO_RETURN_CMD, group=name_group)
|
subprocess.check_call(ZERO_RETURN_CMD, group=name_group)
|
||||||
|
@ -1986,6 +1994,11 @@ class POSIXProcessTestCase(BaseTestCase):
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
subprocess.check_call(ZERO_RETURN_CMD, extra_groups=[-1])
|
subprocess.check_call(ZERO_RETURN_CMD, extra_groups=[-1])
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
subprocess.check_call(ZERO_RETURN_CMD,
|
||||||
|
cwd=os.curdir, env=os.environ,
|
||||||
|
extra_groups=[2**64])
|
||||||
|
|
||||||
if grp is None:
|
if grp is None:
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
subprocess.check_call(ZERO_RETURN_CMD,
|
subprocess.check_call(ZERO_RETURN_CMD,
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix memory leak in :func:`subprocess.Popen` in case an uid (gid) specified in
|
||||||
|
`user` (`group`, `extra_groups`) overflows `uid_t` (`gid_t`).
|
|
@ -772,7 +772,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
gid_t gid, *groups = NULL;
|
gid_t gid, *groups = NULL;
|
||||||
int child_umask;
|
int child_umask;
|
||||||
PyObject *cwd_obj, *cwd_obj2;
|
PyObject *cwd_obj, *cwd_obj2 = NULL;
|
||||||
const char *cwd;
|
const char *cwd;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int need_to_reenable_gc = 0;
|
int need_to_reenable_gc = 0;
|
||||||
|
@ -894,7 +894,6 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
|
||||||
cwd = PyBytes_AsString(cwd_obj2);
|
cwd = PyBytes_AsString(cwd_obj2);
|
||||||
} else {
|
} else {
|
||||||
cwd = NULL;
|
cwd = NULL;
|
||||||
cwd_obj2 = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (groups_list != Py_None) {
|
if (groups_list != Py_None) {
|
||||||
|
@ -1080,6 +1079,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
|
||||||
return PyLong_FromPid(pid);
|
return PyLong_FromPid(pid);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
Py_XDECREF(cwd_obj2);
|
||||||
if (envp)
|
if (envp)
|
||||||
_Py_FreeCharPArray(envp);
|
_Py_FreeCharPArray(envp);
|
||||||
if (argv)
|
if (argv)
|
||||||
|
|
Loading…
Reference in New Issue