Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 /*
0004  * Copyright 2017 John Sperbeck
0005  *
0006  * Test that an access to a mapped but inaccessible area causes a SEGV and
0007  * reports si_code == SEGV_ACCERR.
0008  */
0009 
0010 #include <stdbool.h>
0011 #include <stdio.h>
0012 #include <stdlib.h>
0013 #include <string.h>
0014 #include <unistd.h>
0015 #include <signal.h>
0016 #include <sys/mman.h>
0017 #include <assert.h>
0018 #include <ucontext.h>
0019 
0020 #include "utils.h"
0021 
0022 static bool faulted;
0023 static int si_code;
0024 
0025 static void segv_handler(int n, siginfo_t *info, void *ctxt_v)
0026 {
0027     ucontext_t *ctxt = (ucontext_t *)ctxt_v;
0028     struct pt_regs *regs = ctxt->uc_mcontext.regs;
0029 
0030     faulted = true;
0031     si_code = info->si_code;
0032     regs->nip += 4;
0033 }
0034 
0035 int test_segv_errors(void)
0036 {
0037     struct sigaction act = {
0038         .sa_sigaction = segv_handler,
0039         .sa_flags = SA_SIGINFO,
0040     };
0041     char c, *p = NULL;
0042 
0043     p = mmap(NULL, getpagesize(), 0, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
0044     FAIL_IF(p == MAP_FAILED);
0045 
0046     FAIL_IF(sigaction(SIGSEGV, &act, NULL) != 0);
0047 
0048     faulted = false;
0049     si_code = 0;
0050 
0051     /*
0052      * We just need a compiler barrier, but mb() works and has the nice
0053      * property of being easy to spot in the disassembly.
0054      */
0055     mb();
0056     c = *p;
0057     mb();
0058 
0059     FAIL_IF(!faulted);
0060     FAIL_IF(si_code != SEGV_ACCERR);
0061 
0062     faulted = false;
0063     si_code = 0;
0064 
0065     mb();
0066     *p = c;
0067     mb();
0068 
0069     FAIL_IF(!faulted);
0070     FAIL_IF(si_code != SEGV_ACCERR);
0071 
0072     return 0;
0073 }
0074 
0075 int main(void)
0076 {
0077     return test_harness(test_segv_errors, "segv_errors");
0078 }