Commit faca8553 authored by Victor Stinner's avatar Victor Stinner Committed by T. Wouters

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.
parent 1dc1acbd
...@@ -1681,7 +1681,10 @@ class Popen(object): ...@@ -1681,7 +1681,10 @@ class Popen(object):
and (p2cread == -1 or p2cread > 2) and (p2cread == -1 or p2cread > 2)
and (c2pwrite == -1 or c2pwrite > 2) and (c2pwrite == -1 or c2pwrite > 2)
and (errwrite == -1 or errwrite > 2) and (errwrite == -1 or errwrite > 2)
and not start_new_session): and not start_new_session
and gid is None
and gids is None
and uid is None):
self._posix_spawn(args, executable, env, restore_signals, self._posix_spawn(args, executable, env, restore_signals,
p2cread, p2cwrite, p2cread, p2cwrite,
c2pread, c2pwrite, c2pread, c2pwrite,
......
...@@ -1589,7 +1589,7 @@ class RunFuncTestCase(BaseTestCase): ...@@ -1589,7 +1589,7 @@ class RunFuncTestCase(BaseTestCase):
def _get_test_grp_name(): def _get_test_grp_name():
for name_group in ('staff', 'nogroup', 'grp'): for name_group in ('staff', 'nogroup', 'grp', 'nobody', 'nfsnobody'):
if grp: if grp:
try: try:
grp.getgrnam(name_group) grp.getgrnam(name_group)
...@@ -1768,24 +1768,27 @@ class POSIXProcessTestCase(BaseTestCase): ...@@ -1768,24 +1768,27 @@ class POSIXProcessTestCase(BaseTestCase):
test_users.append(name_uid) test_users.append(name_uid)
for user in test_users: for user in test_users:
with self.subTest(user=user): # posix_spawn() may be used with close_fds=False
try: for close_fds in (False, True):
output = subprocess.check_output( with self.subTest(user=user, close_fds=close_fds):
[sys.executable, "-c", try:
"import os; print(os.getuid())"], output = subprocess.check_output(
user=user) [sys.executable, "-c",
except PermissionError: # errno.EACCES "import os; print(os.getuid())"],
pass user=user,
except OSError as e: close_fds=close_fds)
if e.errno not in (errno.EACCES, errno.EPERM): except PermissionError: # (EACCES, EPERM)
raise pass
else: except OSError as e:
if isinstance(user, str): if e.errno not in (errno.EACCES, errno.EPERM):
user_uid = pwd.getpwnam(user).pw_uid raise
else: else:
user_uid = user if isinstance(user, str):
child_user = int(output) user_uid = pwd.getpwnam(user).pw_uid
self.assertEqual(child_user, user_uid) else:
user_uid = user
child_user = int(output)
self.assertEqual(child_user, user_uid)
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
subprocess.check_call([sys.executable, "-c", "pass"], user=-1) subprocess.check_call([sys.executable, "-c", "pass"], user=-1)
...@@ -1809,23 +1812,25 @@ class POSIXProcessTestCase(BaseTestCase): ...@@ -1809,23 +1812,25 @@ class POSIXProcessTestCase(BaseTestCase):
group_list.append(name_group) group_list.append(name_group)
for group in group_list + [gid]: for group in group_list + [gid]:
with self.subTest(group=group): # posix_spawn() may be used with close_fds=False
try: for close_fds in (False, True):
output = subprocess.check_output( with self.subTest(group=group, close_fds=close_fds):
[sys.executable, "-c", try:
"import os; print(os.getgid())"], output = subprocess.check_output(
group=group) [sys.executable, "-c",
except OSError as e: "import os; print(os.getgid())"],
if e.errno != errno.EPERM: group=group,
raise close_fds=close_fds)
else: except PermissionError: # (EACCES, EPERM)
if isinstance(group, str): pass
group_gid = grp.getgrnam(group).gr_gid
else: else:
group_gid = group if isinstance(group, str):
group_gid = grp.getgrnam(group).gr_gid
else:
group_gid = group
child_group = int(output) child_group = int(output)
self.assertEqual(child_group, group_gid) self.assertEqual(child_group, group_gid)
# make sure we bomb on negative values # make sure we bomb on negative values
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment