1/*
2 * Copyright (c) 2002, Intel Corporation. All rights reserved.
3 * This file is licensed under the GPL license.  For the full content
4 * of this license, see the COPYING file at the top level of this
5 * source tree.
6 *
7 * MPR References within the address range starting at pa and
8 * continuing for len bytes to whole pages following the end
9 * of an object shall result in delivery of a SIGBUS signal.
10 *
11 * Test step:
12 * 1. Map a file with size = 1/2 page_size, while len = 2 * page_size
13 * 2. If Memory Protection option is supported, read the second page
14 *    beyond the object (mapped file) size (NOT the patial page),
15 *    should get SIGBUS;
16 */
17
18#define _XOPEN_SOURCE 600
19
20#include <pthread.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <unistd.h>
24#include <sys/mman.h>
25#include <sys/types.h>
26#include <sys/stat.h>
27#include <sys/wait.h>
28#include <fcntl.h>
29#include <string.h>
30#include <errno.h>
31#include "posixtest.h"
32
33#define TNAME "mmap/11-2.c"
34
35void sigbus_handler (int signum)
36{
37  printf("Test Pass: " TNAME " Trigger SIGBUS\n");
38  exit(PTS_PASS);
39}
40
41int main()
42{
43#ifndef _POSIX_MEMORY_PROTECTION
44	printf("_POSIX_MEMORY_PROTECTION is not defined\n");
45	return PTS_UNTESTED;
46#endif
47  char tmpfname[256];
48  long  page_size;
49  long total_size;
50
51  void *pa = NULL;
52  void *addr = NULL;
53  size_t len;
54  int flag;
55  int fd;
56  off_t off = 0;
57  int prot;
58
59  char *ch = NULL;
60  struct sigaction sa;
61
62  page_size = sysconf(_SC_PAGE_SIZE);
63
64  /* Size of the file to be mapped */
65  total_size = page_size / 2;
66
67  /* mmap 2 pages */
68  len = page_size * 2;
69
70  sigfillset(&sa.sa_mask);
71  sa.sa_handler = sigbus_handler;
72  sigaction(SIGBUS, &sa, NULL);
73
74  /* Create tmp file */
75  snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_mmap_11_2_%ld",
76           (long)getpid());
77  unlink(tmpfname);
78  fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL,
79            S_IRUSR | S_IWUSR);
80  if (fd == -1)
81  {
82    printf(TNAME " Error at open(): %s\n",
83           strerror(errno));
84    exit(PTS_UNRESOLVED);
85  }
86  unlink(tmpfname);
87
88  if (ftruncate(fd, total_size) == -1)
89  {
90    printf(TNAME "Error at ftruncate(): %s\n",
91            strerror(errno));
92    exit(PTS_UNRESOLVED);
93  }
94
95  prot = PROT_READ | PROT_WRITE;
96  flag = MAP_SHARED;
97  off = 0;
98  pa = mmap(addr, len, prot, flag, fd, off);
99  if (pa == MAP_FAILED)
100  {
101    printf("Test FAIL: " TNAME " Error at mmap(): %s\n",
102    	   strerror(errno));
103    exit(PTS_FAIL);
104  }
105
106  /* Read the second page */
107  ch = pa + page_size + 1;
108
109  /* This reference should trigger SIGBUS */
110  *ch = 0;
111
112  /* wait for a while */
113  sleep(1);
114
115  printf("Test Fail: " TNAME " Did not trigger SIGBUS, "
116         "while Memory Protection is enabled\n");
117  exit(PTS_FAIL);
118}
119