brintos

brintos / linux-shallow public Read only

0
0
Text · 1.4 KiB · 06ae76e Raw
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