/* Tests for memory protection keys.
   Copyright (C) 2017-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 <inttypes.h>
#include <setjmp.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <support/check.h>
#include <support/support.h>
#include <support/test-driver.h>
#include <support/xsignal.h>
#include <support/xthread.h>
#include <support/xunistd.h>
#include <sys/mman.h>

/* Used to force threads to wait until the main thread has set up the
   keys as intended.  */
static pthread_barrier_t barrier;

/* The keys used for testing.  These have been allocated with access
   rights set based on their array index.  */
enum { key_count = 4 };
static int keys[key_count];
static volatile int *pages[key_count];

/* Used to report results from the signal handler.  */
static volatile void *sigsegv_addr;
static volatile int sigsegv_code;
static volatile int sigsegv_pkey;
static sigjmp_buf sigsegv_jmp;

/* Used to handle expected read or write faults.  */
static void
sigsegv_handler (int signum, siginfo_t *info, void *context)
{
  sigsegv_addr = info->si_addr;
  sigsegv_code = info->si_code;
  sigsegv_pkey = info->si_pkey;
  siglongjmp (sigsegv_jmp, 2);
}

static const struct sigaction sigsegv_sigaction =
  {
    .sa_flags = SA_RESETHAND | SA_SIGINFO,
    .sa_sigaction = &sigsegv_handler,
  };

/* Check if PAGE is readable (if !WRITE) or writable (if WRITE).  */
static bool
check_page_access (int page, bool write)
{
  /* This is needed to work around bug 22396: On x86-64, siglongjmp
     does not restore the protection key access rights for the current
     thread.  We restore only the access rights for the keys under
     test.  (This is not a general solution to this problem, but it
     allows testing to proceed after a fault.)  */
  unsigned saved_rights[key_count];
  for (int i = 0; i < key_count; ++i)
    saved_rights[i] = pkey_get (keys[i]);

  volatile int *addr = pages[page];
  if (test_verbose > 0)
    {
      printf ("info: checking access at %p (page %d) for %s\n",
              addr, page, write ? "writing" : "reading");
    }
  int result = sigsetjmp (sigsegv_jmp, 1);
  if (result == 0)
    {
      xsigaction (SIGSEGV, &sigsegv_sigaction, NULL);
      if (write)
        *addr = 3;
      else
        (void) *addr;
      xsignal (SIGSEGV, SIG_DFL);
      if (test_verbose > 0)
        puts ("  --> access allowed");
      return true;
    }
  else
    {
      xsignal (SIGSEGV, SIG_DFL);
      if (test_verbose > 0)
        puts ("  --> access denied");
      TEST_COMPARE (result, 2);
      TEST_COMPARE ((uintptr_t) sigsegv_addr, (uintptr_t) addr);
      TEST_COMPARE (sigsegv_code, SEGV_PKUERR);
      TEST_COMPARE (sigsegv_pkey, keys[page]);
      for (int i = 0; i < key_count; ++i)
        TEST_COMPARE (pkey_set (keys[i], saved_rights[i]), 0);
      return false;
    }
}

static volatile sig_atomic_t sigusr1_handler_ran;

/* Used to check that access is revoked in signal handlers.  */
static void
sigusr1_handler (int signum)
{
  TEST_COMPARE (signum, SIGUSR1);
  for (int i = 0; i < key_count; ++i)
    TEST_COMPARE (pkey_get (keys[i]), PKEY_DISABLE_ACCESS);
  sigusr1_handler_ran = 1;
}

/* Used to report results from other threads.  */
struct thread_result
{
  int access_rights[key_count];
  pthread_t next_thread;
};

/* Return the thread's access rights for the keys under test.  */
static void *
get_thread_func (void *closure)
{
  struct thread_result *result = xmalloc (sizeof (*result));
  for (int i = 0; i < key_count; ++i)
    result->access_rights[i] = pkey_get (keys[i]);
  memset (&result->next_thread, 0, sizeof (result->next_thread));
  return result;
}

/* Wait for initialization and then check that the current thread does
   not have access through the keys under test.  */
static void *
delayed_thread_func (void *closure)
{
  bool check_access = *(bool *) closure;
  pthread_barrier_wait (&barrier);
  struct thread_result *result = get_thread_func (NULL);

  if (check_access)
    {
      /* Also check directly.  This code should not run with other
         threads in parallel because of the SIGSEGV handler which is
         installed by check_page_access.  */
      for (int i = 0; i < key_count; ++i)
        {
          TEST_VERIFY (!check_page_access (i, false));
          TEST_VERIFY (!check_page_access (i, true));
        }
    }

  result->next_thread = xpthread_create (NULL, get_thread_func, NULL);
  return result;
}

static int
do_test (void)
{
  long pagesize = xsysconf (_SC_PAGESIZE);

  /* pkey_mprotect with key -1 should work even when there is no
     protection key support.  */
  {
    int *page = xmmap (NULL, pagesize, PROT_NONE,
                       MAP_ANONYMOUS | MAP_PRIVATE, -1);
    TEST_COMPARE (pkey_mprotect (page, pagesize, PROT_READ | PROT_WRITE, -1),
                  0);
    volatile int *vpage = page;
    *vpage = 5;
    TEST_COMPARE (*vpage, 5);
    xmunmap (page, pagesize);
  }

  xpthread_barrier_init (&barrier, NULL, 2);
  bool delayed_thread_check_access = true;
  pthread_t delayed_thread = xpthread_create
    (NULL, &delayed_thread_func, &delayed_thread_check_access);

  keys[0] = pkey_alloc (0, 0);
  if (keys[0] < 0)
    {
      if (errno == ENOSYS)
        FAIL_UNSUPPORTED
          ("kernel does not support memory protection keys");
      if (errno == EINVAL)
        FAIL_UNSUPPORTED
          ("CPU does not support memory protection keys: %m");
      FAIL_EXIT1 ("pkey_alloc: %m");
    }
  TEST_COMPARE (pkey_get (keys[0]), 0);
  for (int i = 1; i < key_count; ++i)
    {
      keys[i] = pkey_alloc (0, i);
      if (keys[i] < 0)
        FAIL_EXIT1 ("pkey_alloc (0, %d): %m", i);
      /* pkey_alloc is supposed to change the current thread's access
         rights for the new key.  */
      TEST_COMPARE (pkey_get (keys[i]), i);
    }
  /* Check that all the keys have the expected access rights for the
     current thread.  */
  for (int i = 0; i < key_count; ++i)
    TEST_COMPARE (pkey_get (keys[i]), i);

  /* Allocate a test page for each key.  */
  for (int i = 0; i < key_count; ++i)
    {
      pages[i] = xmmap (NULL, pagesize, PROT_READ | PROT_WRITE,
                        MAP_ANONYMOUS | MAP_PRIVATE, -1);
      TEST_COMPARE (pkey_mprotect ((void *) pages[i], pagesize,
                                   PROT_READ | PROT_WRITE, keys[i]), 0);
    }

  /* Check that the initial thread does not have access to the new
     keys.  */
  {
    pthread_barrier_wait (&barrier);
    struct thread_result *result = xpthread_join (delayed_thread);
    for (int i = 0; i < key_count; ++i)
      TEST_COMPARE (result->access_rights[i],
                    PKEY_DISABLE_ACCESS);
    struct thread_result *result2 = xpthread_join (result->next_thread);
    for (int i = 0; i < key_count; ++i)
      TEST_COMPARE (result->access_rights[i],
                    PKEY_DISABLE_ACCESS);
    free (result);
    free (result2);
  }

  /* Check that the current thread access rights are inherited by new
     threads.  */
  {
    pthread_t get_thread = xpthread_create (NULL, get_thread_func, NULL);
    struct thread_result *result = xpthread_join (get_thread);
    for (int i = 0; i < key_count; ++i)
      TEST_COMPARE (result->access_rights[i], i);
    free (result);
  }

  for (int i = 0; i < key_count; ++i)
    TEST_COMPARE (pkey_get (keys[i]), i);

  /* Check that in a signal handler, there is no access.  */
  xsignal (SIGUSR1, &sigusr1_handler);
  xraise (SIGUSR1);
  xsignal (SIGUSR1, SIG_DFL);
  TEST_COMPARE (sigusr1_handler_ran, 1);

  /* The first key results in a writable page.  */
  TEST_VERIFY (check_page_access (0, false));
  TEST_VERIFY (check_page_access (0, true));

  /* The other keys do not.   */
  for (int i = 1; i < key_count; ++i)
    {
      if (test_verbose)
        printf ("info: checking access for key %d, bits 0x%x\n",
                i, pkey_get (keys[i]));
      for (int j = 0; j < key_count; ++j)
        TEST_COMPARE (pkey_get (keys[j]), j);
      if (i & PKEY_DISABLE_ACCESS)
        {
          TEST_VERIFY (!check_page_access (i, false));
          TEST_VERIFY (!check_page_access (i, true));
        }
      else
        {
          TEST_VERIFY (i & PKEY_DISABLE_WRITE);
          TEST_VERIFY (check_page_access (i, false));
          TEST_VERIFY (!check_page_access (i, true));
        }
    }

  /* But if we set the current thread's access rights, we gain
     access.  */
  for (int do_write = 0; do_write < 2; ++do_write)
    for (int allowed_key = 0; allowed_key < key_count; ++allowed_key)
      {
        for (int i = 0; i < key_count; ++i)
          if (i == allowed_key)
            {
              if (do_write)
                TEST_COMPARE (pkey_set (keys[i], 0), 0);
              else
                TEST_COMPARE (pkey_set (keys[i], PKEY_DISABLE_WRITE), 0);
            }
          else
            TEST_COMPARE (pkey_set (keys[i], PKEY_DISABLE_ACCESS), 0);

        if (test_verbose)
          printf ("info: key %d is allowed access for %s\n",
                  allowed_key, do_write ? "writing" : "reading");
        for (int i = 0; i < key_count; ++i)
          if (i == allowed_key)
            {
              TEST_VERIFY (check_page_access (i, false));
              TEST_VERIFY (check_page_access (i, true) == do_write);
            }
          else
            {
              TEST_VERIFY (!check_page_access (i, false));
              TEST_VERIFY (!check_page_access (i, true));
            }
      }

  /* Restore access to all keys, and launch a thread which should
     inherit that access.  */
  for (int i = 0; i < key_count; ++i)
    {
      TEST_COMPARE (pkey_set (keys[i], 0), 0);
      TEST_VERIFY (check_page_access (i, false));
      TEST_VERIFY (check_page_access (i, true));
    }
  delayed_thread_check_access = false;
  delayed_thread = xpthread_create
    (NULL, delayed_thread_func, &delayed_thread_check_access);

  TEST_COMPARE (pkey_free (keys[0]), 0);
  /* Second pkey_free will fail because the key has already been
     freed.  */
  TEST_COMPARE (pkey_free (keys[0]),-1);
  TEST_COMPARE (errno, EINVAL);
  for (int i = 1; i < key_count; ++i)
    TEST_COMPARE (pkey_free (keys[i]), 0);

  /* Check what happens to running threads which have access to
     previously allocated protection keys.  The implemented behavior
     is somewhat dubious: Ideally, pkey_free should revoke access to
     that key and pkey_alloc of the same (numeric) key should not
     implicitly confer access to already-running threads, but this is
     not what happens in practice.  */
  {
    /* The limit is in place to avoid running indefinitely in case
       there many keys available.  */
    int *keys_array = xcalloc (100000, sizeof (*keys_array));
    int keys_allocated = 0;
    while (keys_allocated < 100000)
      {
        int new_key = pkey_alloc (0, PKEY_DISABLE_WRITE);
        if (new_key < 0)
          {
            /* No key reuse observed before running out of keys.  */
            TEST_COMPARE (errno, ENOSPC);
            break;
          }
        for (int i = 0; i < key_count; ++i)
          if (new_key == keys[i])
            {
              /* We allocated the key with disabled write access.
                 This should affect the protection state of the
                 existing page.  */
              TEST_VERIFY (check_page_access (i, false));
              TEST_VERIFY (!check_page_access (i, true));

              xpthread_barrier_wait (&barrier);
              struct thread_result *result = xpthread_join (delayed_thread);
              /* The thread which was launched before should still have
                 access to the key.  */
              TEST_COMPARE (result->access_rights[i], 0);
              struct thread_result *result2
                = xpthread_join (result->next_thread);
              /* Same for a thread which is launched afterwards from
                 the old thread.  */
              TEST_COMPARE (result2->access_rights[i], 0);
              free (result);
              free (result2);
              keys_array[keys_allocated++] = new_key;
              goto after_key_search;
            }
        /* Save key for later deallocation.  */
        keys_array[keys_allocated++] = new_key;
      }
  after_key_search:
    /* Deallocate the keys allocated for testing purposes.  */
    for (int j = 0; j < keys_allocated; ++j)
      TEST_COMPARE (pkey_free (keys_array[j]), 0);
    free (keys_array);
  }

  for (int i = 0; i < key_count; ++i)
    xmunmap ((void *) pages[i], pagesize);

  xpthread_barrier_destroy (&barrier);
  return 0;
}

#include <support/test-driver.c>
