]> granicus.if.org Git - python/commitdiff
bpo-36046: posix_spawn() doesn't support uid/gid (GH-16384)
authorVictor Stinner <vstinner@redhat.com>
Wed, 25 Sep 2019 13:52:49 +0000 (15:52 +0200)
committerT. Wouters <thomas@python.org>
Wed, 25 Sep 2019 13:52:49 +0000 (15:52 +0200)
* 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.

Lib/subprocess.py
Lib/test/test_subprocess.py

index 85e7969c0928ca942ae8bc92d03085644d3946a3..1016874c4a7f4ea357c756277a0fcba680a5be46 100644 (file)
@@ -1681,7 +1681,10 @@ class Popen(object):
                     and (p2cread == -1 or p2cread > 2)
                     and (c2pwrite == -1 or c2pwrite > 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,
                                   p2cread, p2cwrite,
                                   c2pread, c2pwrite,
index 42f376cda5d27aa3aa26469c24920b9b7b462d1d..22516402da0e894363a33031436280de9c2b02da 100644 (file)
@@ -1589,7 +1589,7 @@ class RunFuncTestCase(BaseTestCase):
 
 
 def _get_test_grp_name():
-    for name_group in ('staff', 'nogroup', 'grp'):
+    for name_group in ('staff', 'nogroup', 'grp', 'nobody', 'nfsnobody'):
         if grp:
             try:
                 grp.getgrnam(name_group)
@@ -1768,24 +1768,27 @@ class POSIXProcessTestCase(BaseTestCase):
             test_users.append(name_uid)
 
         for user in test_users:
-            with self.subTest(user=user):
-                try:
-                    output = subprocess.check_output(
-                            [sys.executable, "-c",
-                             "import os; print(os.getuid())"],
-                            user=user)
-                except PermissionError:  # errno.EACCES
-                    pass
-                except OSError as e:
-                    if e.errno not in (errno.EACCES, errno.EPERM):
-                        raise
-                else:
-                    if isinstance(user, str):
-                        user_uid = pwd.getpwnam(user).pw_uid
+            # posix_spawn() may be used with close_fds=False
+            for close_fds in (False, True):
+                with self.subTest(user=user, close_fds=close_fds):
+                    try:
+                        output = subprocess.check_output(
+                                [sys.executable, "-c",
+                                 "import os; print(os.getuid())"],
+                                user=user,
+                                close_fds=close_fds)
+                    except PermissionError:  # (EACCES, EPERM)
+                        pass
+                    except OSError as e:
+                        if e.errno not in (errno.EACCES, errno.EPERM):
+                            raise
                     else:
-                        user_uid = user
-                    child_user = int(output)
-                    self.assertEqual(child_user, user_uid)
+                        if isinstance(user, str):
+                            user_uid = pwd.getpwnam(user).pw_uid
+                        else:
+                            user_uid = user
+                        child_user = int(output)
+                        self.assertEqual(child_user, user_uid)
 
         with self.assertRaises(ValueError):
             subprocess.check_call([sys.executable, "-c", "pass"], user=-1)
@@ -1809,23 +1812,25 @@ class POSIXProcessTestCase(BaseTestCase):
             group_list.append(name_group)
 
         for group in group_list + [gid]:
-            with self.subTest(group=group):
-                try:
-                    output = subprocess.check_output(
-                            [sys.executable, "-c",
-                             "import os; print(os.getgid())"],
-                            group=group)
-                except OSError as e:
-                    if e.errno != errno.EPERM:
-                        raise
-                else:
-                    if isinstance(group, str):
-                        group_gid = grp.getgrnam(group).gr_gid
+            # posix_spawn() may be used with close_fds=False
+            for close_fds in (False, True):
+                with self.subTest(group=group, close_fds=close_fds):
+                    try:
+                        output = subprocess.check_output(
+                                [sys.executable, "-c",
+                                 "import os; print(os.getgid())"],
+                                group=group,
+                                close_fds=close_fds)
+                    except PermissionError:  # (EACCES, EPERM)
+                        pass
                     else:
-                        group_gid = group
+                        if isinstance(group, str):
+                            group_gid = grp.getgrnam(group).gr_gid
+                        else:
+                            group_gid = group
 
-                    child_group = int(output)
-                    self.assertEqual(child_group, group_gid)
+                        child_group = int(output)
+                        self.assertEqual(child_group, group_gid)
 
         # make sure we bomb on negative values
         with self.assertRaises(ValueError):