root/tools/testing/selftests/x86/syscall_numbering.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. check_enosys
  2. test_x32_without_x32_bit
  3. main

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 /*
   3  * syscall_arg_fault.c - tests faults 32-bit fast syscall stack args
   4  * Copyright (c) 2018 Andrew Lutomirski
   5  */
   6 
   7 #define _GNU_SOURCE
   8 
   9 #include <stdlib.h>
  10 #include <stdio.h>
  11 #include <stdbool.h>
  12 #include <errno.h>
  13 #include <unistd.h>
  14 #include <syscall.h>
  15 
  16 static int nerrs;
  17 
  18 #define X32_BIT 0x40000000UL
  19 
  20 static void check_enosys(unsigned long nr, bool *ok)
  21 {
  22         /* If this fails, a segfault is reasonably likely. */
  23         fflush(stdout);
  24 
  25         long ret = syscall(nr, 0, 0, 0, 0, 0, 0);
  26         if (ret == 0) {
  27                 printf("[FAIL]\tsyscall %lu succeeded, but it should have failed\n", nr);
  28                 *ok = false;
  29         } else if (errno != ENOSYS) {
  30                 printf("[FAIL]\tsyscall %lu had error code %d, but it should have reported ENOSYS\n", nr, errno);
  31                 *ok = false;
  32         }
  33 }
  34 
  35 static void test_x32_without_x32_bit(void)
  36 {
  37         bool ok = true;
  38 
  39         /*
  40          * Syscalls 512-547 are "x32" syscalls.  They are intended to be
  41          * called with the x32 (0x40000000) bit set.  Calling them without
  42          * the x32 bit set is nonsense and should not work.
  43          */
  44         printf("[RUN]\tChecking syscalls 512-547\n");
  45         for (int i = 512; i <= 547; i++)
  46                 check_enosys(i, &ok);
  47 
  48         /*
  49          * Check that a handful of 64-bit-only syscalls are rejected if the x32
  50          * bit is set.
  51          */
  52         printf("[RUN]\tChecking some 64-bit syscalls in x32 range\n");
  53         check_enosys(16 | X32_BIT, &ok);        /* ioctl */
  54         check_enosys(19 | X32_BIT, &ok);        /* readv */
  55         check_enosys(20 | X32_BIT, &ok);        /* writev */
  56 
  57         /*
  58          * Check some syscalls with high bits set.
  59          */
  60         printf("[RUN]\tChecking numbers above 2^32-1\n");
  61         check_enosys((1UL << 32), &ok);
  62         check_enosys(X32_BIT | (1UL << 32), &ok);
  63 
  64         if (!ok)
  65                 nerrs++;
  66         else
  67                 printf("[OK]\tThey all returned -ENOSYS\n");
  68 }
  69 
  70 int main()
  71 {
  72         /*
  73          * Anyone diagnosing a failure will want to know whether the kernel
  74          * supports x32.  Tell them.
  75          */
  76         printf("\tChecking for x32...");
  77         fflush(stdout);
  78         if (syscall(39 | X32_BIT, 0, 0, 0, 0, 0, 0) >= 0) {
  79                 printf(" supported\n");
  80         } else if (errno == ENOSYS) {
  81                 printf(" not supported\n");
  82         } else {
  83                 printf(" confused\n");
  84         }
  85 
  86         test_x32_without_x32_bit();
  87 
  88         return nerrs ? 1 : 0;
  89 }

/* [<][>][^][v][top][bottom][index][help] */