/* Copyright (C) 2014-2018 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <unistd.h>

/* Check that a partial setuid failure aborts the process. */

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond_send;
static void (*func_sent) (void);
static pthread_cond_t cond_recv;

#define FAIL(fmt, ...) \
  do { printf ("FAIL: " fmt "\n", __VA_ARGS__); _exit (1); } while (0)

static void *
thread_func (void *ctx __attribute__ ((unused)))
{
  int ret = pthread_mutex_lock (&mutex);
  if (ret != 0)
    FAIL ("pthread_mutex_lock (thread): %d", ret);

  while (true)
    {
      if (func_sent != NULL)
	{
	  void (*func) (void) = func_sent;
	  ret = pthread_mutex_unlock (&mutex);
	  if (ret != 0)
	    FAIL ("pthread_mutex_unlock (thread): %d", ret);
	  func ();
	  ret = pthread_mutex_lock (&mutex);
	  if (ret != 0)
	    FAIL ("pthread_mutex_lock (thread): %d", ret);
	  func_sent = NULL;
	  ret = pthread_cond_signal (&cond_recv);
	  if (ret != 0)
	    FAIL ("pthread_cond_signal (recv): %d", ret);
	}
      ret = pthread_cond_wait (&cond_send, &mutex);
      if (ret != 0)
	FAIL ("pthread_cond_wait (send): %d", ret);
    }
  return NULL;
}

static void
run_on_thread (void (*func) (void))
{
  int ret = pthread_mutex_lock (&mutex);
  if (ret != 0)
    FAIL ("pthread_mutex_lock (%s): %d", __func__, ret);
  func_sent = func;
  ret = pthread_mutex_unlock (&mutex);
  if (ret != 0)
    FAIL ("pthread_mutex_unlock (%s): %d", __func__, ret);

  ret = pthread_cond_signal (&cond_send);
  if (ret != 0)
    FAIL ("pthread_mutex_lock (%s): %d", __func__, ret);

  ret = pthread_mutex_lock (&mutex);
  if (ret != 0)
    FAIL ("pthread_mutex_lock (%s): %d", __func__, ret);

  while (func_sent != NULL)
    {
      ret = pthread_cond_wait (&cond_recv, &mutex);
      if (ret != 0)
	FAIL ("pthread_mutex_wait (%s): %d", __func__, ret);
    }
  ret = pthread_mutex_unlock (&mutex);
  if (ret != 0)
    FAIL ("pthread_mutex_unlock (%s): %d", __func__, ret);
}

static void
change_thread_ids (void)
{
  long ret = syscall (__NR_setresuid, 2001, 2002, 2003);
  if (ret != 0)
    FAIL ("setresuid (2001, 2002, 2003): %ld", ret);
}

static uid_t ruid, euid, suid;

static void
get_thread_ids (void)
{
  if (getresuid (&ruid, &euid, &suid) < 0)
    FAIL ("getresuid: %m (%d)", errno);
}

static void
abort_expected (int signal __attribute__ ((unused)))
{
  _exit (0);
}

static int
do_test (void)
{
  pthread_t thread;
  int ret = pthread_create (&thread, NULL, thread_func, NULL);
  if (ret != 0)
    FAIL ("pthread_create: %d", ret);

  run_on_thread (change_thread_ids);

  signal (SIGABRT, &abort_expected);
  /* This should abort the process.  */
  if (setresuid (1001, 1002, 1003) < 0)
    FAIL ("setresuid: %m (%d)", errno);
  signal (SIGABRT, SIG_DFL);

  /* If we get here, check that the kernel did the right thing. */
  run_on_thread (get_thread_ids);
  if (ruid != 1001 || euid != 1002 || suid != 1003)
    FAIL ("unexpected UIDs after setuid: %ld, %ld, %ld",
	  (long) ruid, (long) euid, (long) suid);
  return 0;
}

#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
