79 lines · c
1// SPDX-License-Identifier: GPL-2.02 3/*4 * Copyright 2017 John Sperbeck5 *6 * Test that an access to a mapped but inaccessible area causes a SEGV and7 * reports si_code == SEGV_ACCERR.8 */9 10#include <stdbool.h>11#include <stdio.h>12#include <stdlib.h>13#include <string.h>14#include <unistd.h>15#include <signal.h>16#include <sys/mman.h>17#include <assert.h>18#include <ucontext.h>19 20#include "utils.h"21 22static bool faulted;23static int si_code;24 25static void segv_handler(int n, siginfo_t *info, void *ctxt_v)26{27 ucontext_t *ctxt = (ucontext_t *)ctxt_v;28 struct pt_regs *regs = ctxt->uc_mcontext.regs;29 30 faulted = true;31 si_code = info->si_code;32 regs->nip += 4;33}34 35int test_segv_errors(void)36{37 struct sigaction act = {38 .sa_sigaction = segv_handler,39 .sa_flags = SA_SIGINFO,40 };41 char c, *p = NULL;42 43 p = mmap(NULL, getpagesize(), 0, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);44 FAIL_IF(p == MAP_FAILED);45 46 FAIL_IF(sigaction(SIGSEGV, &act, NULL) != 0);47 48 faulted = false;49 si_code = 0;50 51 /*52 * We just need a compiler barrier, but mb() works and has the nice53 * property of being easy to spot in the disassembly.54 */55 mb();56 c = *p;57 mb();58 59 FAIL_IF(!faulted);60 FAIL_IF(si_code != SEGV_ACCERR);61 62 faulted = false;63 si_code = 0;64 65 mb();66 *p = c;67 mb();68 69 FAIL_IF(!faulted);70 FAIL_IF(si_code != SEGV_ACCERR);71 72 return 0;73}74 75int main(void)76{77 return test_harness(test_segv_errors, "segv_errors");78}79