about summary refs log tree commit diff
path: root/nptl/allocatestack.c
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2021-04-21 19:49:51 +0200
committerFlorian Weimer <fweimer@redhat.com>2021-04-21 19:49:51 +0200
commit486010a3c8cb59df19995eac964ef51e627287a4 (patch)
treea2a3f987c5ed5446355fed93a1b9c4be57ada486 /nptl/allocatestack.c
parent08129b155e50f01588ec6e675fc76637cb22eb01 (diff)
downloadglibc-486010a3c8cb59df19995eac964ef51e627287a4.tar.gz
glibc-486010a3c8cb59df19995eac964ef51e627287a4.tar.xz
glibc-486010a3c8cb59df19995eac964ef51e627287a4.zip
nptl: Move setxid broadcast implementation into libc
The signal handler is exported as __nptl_setxid_sighandler, so
that the libpthread initialization code can install it.  This
is sufficient for now because it is guarantueed to happen before
the first pthread_create call.
Diffstat (limited to 'nptl/allocatestack.c')
-rw-r--r--nptl/allocatestack.c209
1 files changed, 0 insertions, 209 deletions
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index 00fddbd409..f1270c3109 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -953,215 +953,6 @@ __reclaim_stacks (void)
 }
 
 
-static void
-setxid_mark_thread (struct xid_command *cmdp, struct pthread *t)
-{
-  int ch;
-
-  /* Wait until this thread is cloned.  */
-  if (t->setxid_futex == -1
-      && ! atomic_compare_and_exchange_bool_acq (&t->setxid_futex, -2, -1))
-    do
-      futex_wait_simple (&t->setxid_futex, -2, FUTEX_PRIVATE);
-    while (t->setxid_futex == -2);
-
-  /* Don't let the thread exit before the setxid handler runs.  */
-  t->setxid_futex = 0;
-
-  do
-    {
-      ch = t->cancelhandling;
-
-      /* If the thread is exiting right now, ignore it.  */
-      if ((ch & EXITING_BITMASK) != 0)
-	{
-	  /* Release the futex if there is no other setxid in
-	     progress.  */
-	  if ((ch & SETXID_BITMASK) == 0)
-	    {
-	      t->setxid_futex = 1;
-	      futex_wake (&t->setxid_futex, 1, FUTEX_PRIVATE);
-	    }
-	  return;
-	}
-    }
-  while (atomic_compare_and_exchange_bool_acq (&t->cancelhandling,
-					       ch | SETXID_BITMASK, ch));
-}
-
-
-static void
-setxid_unmark_thread (struct xid_command *cmdp, struct pthread *t)
-{
-  int ch;
-
-  do
-    {
-      ch = t->cancelhandling;
-      if ((ch & SETXID_BITMASK) == 0)
-	return;
-    }
-  while (atomic_compare_and_exchange_bool_acq (&t->cancelhandling,
-					       ch & ~SETXID_BITMASK, ch));
-
-  /* Release the futex just in case.  */
-  t->setxid_futex = 1;
-  futex_wake (&t->setxid_futex, 1, FUTEX_PRIVATE);
-}
-
-
-static int
-setxid_signal_thread (struct xid_command *cmdp, struct pthread *t)
-{
-  if ((t->cancelhandling & SETXID_BITMASK) == 0)
-    return 0;
-
-  int val;
-  pid_t pid = __getpid ();
-  val = INTERNAL_SYSCALL_CALL (tgkill, pid, t->tid, SIGSETXID);
-
-  /* If this failed, it must have had not started yet or else exited.  */
-  if (!INTERNAL_SYSCALL_ERROR_P (val))
-    {
-      atomic_increment (&cmdp->cntr);
-      return 1;
-    }
-  else
-    return 0;
-}
-
-/* Check for consistency across set*id system call results.  The abort
-   should not happen as long as all privileges changes happen through
-   the glibc wrappers.  ERROR must be 0 (no error) or an errno
-   code.  */
-void
-attribute_hidden
-__nptl_setxid_error (struct xid_command *cmdp, int error)
-{
-  do
-    {
-      int olderror = cmdp->error;
-      if (olderror == error)
-	break;
-      if (olderror != -1)
-	{
-	  /* Mismatch between current and previous results.  Save the
-	     error value to memory so that is not clobbered by the
-	     abort function and preserved in coredumps.  */
-	  volatile int xid_err __attribute__((unused)) = error;
-	  abort ();
-	}
-    }
-  while (atomic_compare_and_exchange_bool_acq (&cmdp->error, error, -1));
-}
-
-int
-attribute_hidden
-__nptl_setxid (struct xid_command *cmdp)
-{
-  int signalled;
-  int result;
-  lll_lock (GL (dl_stack_cache_lock), LLL_PRIVATE);
-
-  __xidcmd = cmdp;
-  cmdp->cntr = 0;
-  cmdp->error = -1;
-
-  struct pthread *self = THREAD_SELF;
-
-  /* Iterate over the list with system-allocated threads first.  */
-  list_t *runp;
-  list_for_each (runp, &GL (dl_stack_used))
-    {
-      struct pthread *t = list_entry (runp, struct pthread, list);
-      if (t == self)
-	continue;
-
-      setxid_mark_thread (cmdp, t);
-    }
-
-  /* Now the list with threads using user-allocated stacks.  */
-  list_for_each (runp, &GL (dl_stack_user))
-    {
-      struct pthread *t = list_entry (runp, struct pthread, list);
-      if (t == self)
-	continue;
-
-      setxid_mark_thread (cmdp, t);
-    }
-
-  /* Iterate until we don't succeed in signalling anyone.  That means
-     we have gotten all running threads, and their children will be
-     automatically correct once started.  */
-  do
-    {
-      signalled = 0;
-
-      list_for_each (runp, &GL (dl_stack_used))
-	{
-	  struct pthread *t = list_entry (runp, struct pthread, list);
-	  if (t == self)
-	    continue;
-
-	  signalled += setxid_signal_thread (cmdp, t);
-	}
-
-      list_for_each (runp, &GL (dl_stack_user))
-	{
-	  struct pthread *t = list_entry (runp, struct pthread, list);
-	  if (t == self)
-	    continue;
-
-	  signalled += setxid_signal_thread (cmdp, t);
-	}
-
-      int cur = cmdp->cntr;
-      while (cur != 0)
-	{
-	  futex_wait_simple ((unsigned int *) &cmdp->cntr, cur,
-			     FUTEX_PRIVATE);
-	  cur = cmdp->cntr;
-	}
-    }
-  while (signalled != 0);
-
-  /* Clean up flags, so that no thread blocks during exit waiting
-     for a signal which will never come.  */
-  list_for_each (runp, &GL (dl_stack_used))
-    {
-      struct pthread *t = list_entry (runp, struct pthread, list);
-      if (t == self)
-	continue;
-
-      setxid_unmark_thread (cmdp, t);
-    }
-
-  list_for_each (runp, &GL (dl_stack_user))
-    {
-      struct pthread *t = list_entry (runp, struct pthread, list);
-      if (t == self)
-	continue;
-
-      setxid_unmark_thread (cmdp, t);
-    }
-
-  /* This must be last, otherwise the current thread might not have
-     permissions to send SIGSETXID syscall to the other threads.  */
-  result = INTERNAL_SYSCALL_NCS (cmdp->syscall_no, 3,
-				 cmdp->id[0], cmdp->id[1], cmdp->id[2]);
-  int error = 0;
-  if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result)))
-    {
-      error = INTERNAL_SYSCALL_ERRNO (result);
-      __set_errno (error);
-      result = -1;
-    }
-  __nptl_setxid_error (cmdp, error);
-
-  lll_unlock (GL (dl_stack_cache_lock), LLL_PRIVATE);
-  return result;
-}
-
 static inline void __attribute__((always_inline))
 init_one_static_tls (struct pthread *curp, struct link_map *map)
 {