Skip to content

Commit c12afa9

Browse files
[3.9] bpo-42146: Fix memory leak in subprocess.Popen() in case of uid/gid overflow (GH-22966) (GH-22980)
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`. (cherry picked from commit c0590c0) Co-authored-by: Alexey Izbyshev <[email protected]> Automerge-Triggered-By: GH:gpshead
1 parent 0b290dd commit c12afa9

File tree

3 files changed

+17
-2
lines changed

3 files changed

+17
-2
lines changed

Lib/test/test_subprocess.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1826,6 +1826,10 @@ def test_user(self):
18261826
with self.assertRaises(ValueError):
18271827
subprocess.check_call(ZERO_RETURN_CMD, user=-1)
18281828

1829+
with self.assertRaises(OverflowError):
1830+
subprocess.check_call(ZERO_RETURN_CMD,
1831+
cwd=os.curdir, env=os.environ, user=2**64)
1832+
18291833
if pwd is None and name_uid is not None:
18301834
with self.assertRaises(ValueError):
18311835
subprocess.check_call(ZERO_RETURN_CMD, user=name_uid)
@@ -1869,6 +1873,10 @@ def test_group(self):
18691873
with self.assertRaises(ValueError):
18701874
subprocess.check_call(ZERO_RETURN_CMD, group=-1)
18711875

1876+
with self.assertRaises(OverflowError):
1877+
subprocess.check_call(ZERO_RETURN_CMD,
1878+
cwd=os.curdir, env=os.environ, group=2**64)
1879+
18721880
if grp is None:
18731881
with self.assertRaises(ValueError):
18741882
subprocess.check_call(ZERO_RETURN_CMD, group=name_group)
@@ -1917,6 +1925,11 @@ def test_extra_groups(self):
19171925
with self.assertRaises(ValueError):
19181926
subprocess.check_call(ZERO_RETURN_CMD, extra_groups=[-1])
19191927

1928+
with self.assertRaises(ValueError):
1929+
subprocess.check_call(ZERO_RETURN_CMD,
1930+
cwd=os.curdir, env=os.environ,
1931+
extra_groups=[2**64])
1932+
19201933
if grp is None:
19211934
with self.assertRaises(ValueError):
19221935
subprocess.check_call(ZERO_RETURN_CMD,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix memory leak in :func:`subprocess.Popen` in case an uid (gid) specified in
2+
`user` (`group`, `extra_groups`) overflows `uid_t` (`gid_t`).

Modules/_posixsubprocess.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
626626
uid_t uid;
627627
gid_t gid, *groups = NULL;
628628
int child_umask;
629-
PyObject *cwd_obj, *cwd_obj2;
629+
PyObject *cwd_obj, *cwd_obj2 = NULL;
630630
const char *cwd;
631631
pid_t pid;
632632
int need_to_reenable_gc = 0;
@@ -748,7 +748,6 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
748748
cwd = PyBytes_AsString(cwd_obj2);
749749
} else {
750750
cwd = NULL;
751-
cwd_obj2 = NULL;
752751
}
753752

754753
if (groups_list != Py_None) {
@@ -908,6 +907,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
908907
return PyLong_FromPid(pid);
909908

910909
cleanup:
910+
Py_XDECREF(cwd_obj2);
911911
if (envp)
912912
_Py_FreeCharPArray(envp);
913913
if (argv)

0 commit comments

Comments
 (0)