Skip to content

Commit faca855

Browse files
vstinnerYhg1s
authored andcommitted
bpo-36046: posix_spawn() doesn't support uid/gid (GH-16384)
* subprocess.Popen now longer uses posix_spawn() if uid, gid or gids are set. * test_subprocess: add "nobody" and "nfsnobody" group names for test_group(). * test_subprocess: test_user() and test_group() are now also tested with close_fds=False.
1 parent 1dc1acb commit faca855

File tree

2 files changed

+42
-34
lines changed

2 files changed

+42
-34
lines changed

Lib/subprocess.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1681,7 +1681,10 @@ def _execute_child(self, args, executable, preexec_fn, close_fds,
16811681
and (p2cread == -1 or p2cread > 2)
16821682
and (c2pwrite == -1 or c2pwrite > 2)
16831683
and (errwrite == -1 or errwrite > 2)
1684-
and not start_new_session):
1684+
and not start_new_session
1685+
and gid is None
1686+
and gids is None
1687+
and uid is None):
16851688
self._posix_spawn(args, executable, env, restore_signals,
16861689
p2cread, p2cwrite,
16871690
c2pread, c2pwrite,

Lib/test/test_subprocess.py

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,7 +1589,7 @@ def test_run_with_shell_timeout_and_capture_output(self):
15891589

15901590

15911591
def _get_test_grp_name():
1592-
for name_group in ('staff', 'nogroup', 'grp'):
1592+
for name_group in ('staff', 'nogroup', 'grp', 'nobody', 'nfsnobody'):
15931593
if grp:
15941594
try:
15951595
grp.getgrnam(name_group)
@@ -1768,24 +1768,27 @@ def test_user(self):
17681768
test_users.append(name_uid)
17691769

17701770
for user in test_users:
1771-
with self.subTest(user=user):
1772-
try:
1773-
output = subprocess.check_output(
1774-
[sys.executable, "-c",
1775-
"import os; print(os.getuid())"],
1776-
user=user)
1777-
except PermissionError: # errno.EACCES
1778-
pass
1779-
except OSError as e:
1780-
if e.errno not in (errno.EACCES, errno.EPERM):
1781-
raise
1782-
else:
1783-
if isinstance(user, str):
1784-
user_uid = pwd.getpwnam(user).pw_uid
1771+
# posix_spawn() may be used with close_fds=False
1772+
for close_fds in (False, True):
1773+
with self.subTest(user=user, close_fds=close_fds):
1774+
try:
1775+
output = subprocess.check_output(
1776+
[sys.executable, "-c",
1777+
"import os; print(os.getuid())"],
1778+
user=user,
1779+
close_fds=close_fds)
1780+
except PermissionError: # (EACCES, EPERM)
1781+
pass
1782+
except OSError as e:
1783+
if e.errno not in (errno.EACCES, errno.EPERM):
1784+
raise
17851785
else:
1786-
user_uid = user
1787-
child_user = int(output)
1788-
self.assertEqual(child_user, user_uid)
1786+
if isinstance(user, str):
1787+
user_uid = pwd.getpwnam(user).pw_uid
1788+
else:
1789+
user_uid = user
1790+
child_user = int(output)
1791+
self.assertEqual(child_user, user_uid)
17891792

17901793
with self.assertRaises(ValueError):
17911794
subprocess.check_call([sys.executable, "-c", "pass"], user=-1)
@@ -1809,23 +1812,25 @@ def test_group(self):
18091812
group_list.append(name_group)
18101813

18111814
for group in group_list + [gid]:
1812-
with self.subTest(group=group):
1813-
try:
1814-
output = subprocess.check_output(
1815-
[sys.executable, "-c",
1816-
"import os; print(os.getgid())"],
1817-
group=group)
1818-
except OSError as e:
1819-
if e.errno != errno.EPERM:
1820-
raise
1821-
else:
1822-
if isinstance(group, str):
1823-
group_gid = grp.getgrnam(group).gr_gid
1815+
# posix_spawn() may be used with close_fds=False
1816+
for close_fds in (False, True):
1817+
with self.subTest(group=group, close_fds=close_fds):
1818+
try:
1819+
output = subprocess.check_output(
1820+
[sys.executable, "-c",
1821+
"import os; print(os.getgid())"],
1822+
group=group,
1823+
close_fds=close_fds)
1824+
except PermissionError: # (EACCES, EPERM)
1825+
pass
18241826
else:
1825-
group_gid = group
1827+
if isinstance(group, str):
1828+
group_gid = grp.getgrnam(group).gr_gid
1829+
else:
1830+
group_gid = group
18261831

1827-
child_group = int(output)
1828-
self.assertEqual(child_group, group_gid)
1832+
child_group = int(output)
1833+
self.assertEqual(child_group, group_gid)
18291834

18301835
# make sure we bomb on negative values
18311836
with self.assertRaises(ValueError):

0 commit comments

Comments
 (0)