1*433d6423SLionel Sambuc
2*433d6423SLionel Sambuc #include <stdio.h>
3*433d6423SLionel Sambuc #include <stdlib.h>
4*433d6423SLionel Sambuc #include <fcntl.h>
5*433d6423SLionel Sambuc #include <unistd.h>
6*433d6423SLionel Sambuc #include <errno.h>
7*433d6423SLionel Sambuc #include <sys/mman.h>
8*433d6423SLionel Sambuc #include <sys/wait.h>
9*433d6423SLionel Sambuc
10*433d6423SLionel Sambuc int max_error = 2;
11*433d6423SLionel Sambuc #include "common.h"
12*433d6423SLionel Sambuc
13*433d6423SLionel Sambuc
14*433d6423SLionel Sambuc int subtest = 0;
15*433d6423SLionel Sambuc
16*433d6423SLionel Sambuc int
main(int argc,char * argv[])17*433d6423SLionel Sambuc main(int argc, char *argv[])
18*433d6423SLionel Sambuc {
19*433d6423SLionel Sambuc #define CHUNKSIZE 8192
20*433d6423SLionel Sambuc #define CHUNKS1 3
21*433d6423SLionel Sambuc #define CHUNKS2 2
22*433d6423SLionel Sambuc #define CHUNKS (CHUNKS1+CHUNKS2)
23*433d6423SLionel Sambuc #define LARGESIZE 262144
24*433d6423SLionel Sambuc int i, fd;
25*433d6423SLionel Sambuc char *v[CHUNKS];
26*433d6423SLionel Sambuc #define STARTV 0x90000000
27*433d6423SLionel Sambuc char *vaddr = (char *) STARTV;
28*433d6423SLionel Sambuc ssize_t l;
29*433d6423SLionel Sambuc pid_t f;
30*433d6423SLionel Sambuc
31*433d6423SLionel Sambuc start(44);
32*433d6423SLionel Sambuc
33*433d6423SLionel Sambuc for(i = 0; i < CHUNKS; i++) {
34*433d6423SLionel Sambuc v[i] = mmap(vaddr, CHUNKSIZE, PROT_READ|PROT_WRITE, 0,
35*433d6423SLionel Sambuc -1, 0);
36*433d6423SLionel Sambuc if(v[i] == MAP_FAILED) {
37*433d6423SLionel Sambuc perror("mmap");
38*433d6423SLionel Sambuc fprintf(stderr, "mmap failed\n");
39*433d6423SLionel Sambuc quit();
40*433d6423SLionel Sambuc }
41*433d6423SLionel Sambuc if(v[i] != vaddr) {
42*433d6423SLionel Sambuc fprintf(stderr,
43*433d6423SLionel Sambuc "mmap said 0x%p but i wanted 0x%p\n",
44*433d6423SLionel Sambuc v[i], vaddr);
45*433d6423SLionel Sambuc quit();
46*433d6423SLionel Sambuc }
47*433d6423SLionel Sambuc vaddr += CHUNKSIZE;
48*433d6423SLionel Sambuc }
49*433d6423SLionel Sambuc
50*433d6423SLionel Sambuc #define DEV_ZERO "/dev/zero"
51*433d6423SLionel Sambuc if((fd=open(DEV_ZERO, O_RDONLY)) < 0) {
52*433d6423SLionel Sambuc perror("open");
53*433d6423SLionel Sambuc fprintf(stderr, "open failed for %s\n", DEV_ZERO);
54*433d6423SLionel Sambuc quit();
55*433d6423SLionel Sambuc }
56*433d6423SLionel Sambuc
57*433d6423SLionel Sambuc #define TOTAL1 (CHUNKS1*CHUNKSIZE)
58*433d6423SLionel Sambuc /* Make single read cross region boundary. */
59*433d6423SLionel Sambuc if((l=read(fd, v[0], TOTAL1)) != TOTAL1) {
60*433d6423SLionel Sambuc fprintf(stderr, "read %d but expected %d\n", l, TOTAL1);
61*433d6423SLionel Sambuc quit();
62*433d6423SLionel Sambuc }
63*433d6423SLionel Sambuc
64*433d6423SLionel Sambuc /* Force single copy to cross region boundary. */
65*433d6423SLionel Sambuc {
66*433d6423SLionel Sambuc char *t;
67*433d6423SLionel Sambuc t = v[CHUNKS1]+CHUNKSIZE-2;
68*433d6423SLionel Sambuc if((l=read(fd, t, CHUNKSIZE)) != CHUNKSIZE) {
69*433d6423SLionel Sambuc fprintf(stderr, "read %d but expected %d\n", l, CHUNKSIZE);
70*433d6423SLionel Sambuc quit();
71*433d6423SLionel Sambuc }
72*433d6423SLionel Sambuc }
73*433d6423SLionel Sambuc
74*433d6423SLionel Sambuc /* Now start a child to test bogus memory access */
75*433d6423SLionel Sambuc if((f = fork()) == -1) {
76*433d6423SLionel Sambuc perror("fork");
77*433d6423SLionel Sambuc quit();
78*433d6423SLionel Sambuc }
79*433d6423SLionel Sambuc
80*433d6423SLionel Sambuc if(f > 0) {
81*433d6423SLionel Sambuc int st;
82*433d6423SLionel Sambuc /* Parent waits. */
83*433d6423SLionel Sambuc if(waitpid(f, &st, 0) < 0) {
84*433d6423SLionel Sambuc perror("waitpid");
85*433d6423SLionel Sambuc quit();
86*433d6423SLionel Sambuc }
87*433d6423SLionel Sambuc if(!WIFEXITED(st)) {
88*433d6423SLionel Sambuc fprintf(stderr, "child not signaled\n");
89*433d6423SLionel Sambuc quit();
90*433d6423SLionel Sambuc }
91*433d6423SLionel Sambuc if(WEXITSTATUS(st) != 0) {
92*433d6423SLionel Sambuc fprintf(stderr, "child exited with nonzero status\n");
93*433d6423SLionel Sambuc quit();
94*433d6423SLionel Sambuc }
95*433d6423SLionel Sambuc } else {
96*433d6423SLionel Sambuc /* Child performs bogus read */
97*433d6423SLionel Sambuc int res;
98*433d6423SLionel Sambuc char *buf = v[CHUNKS-1];
99*433d6423SLionel Sambuc errno = 0;
100*433d6423SLionel Sambuc res = read(fd, buf, LARGESIZE);
101*433d6423SLionel Sambuc if(res >= 0) {
102*433d6423SLionel Sambuc fprintf(stderr, "res %d\n", res);
103*433d6423SLionel Sambuc quit();
104*433d6423SLionel Sambuc }
105*433d6423SLionel Sambuc if(errno != EFAULT) {
106*433d6423SLionel Sambuc fprintf(stderr, "errno %d\n", errno);
107*433d6423SLionel Sambuc quit();
108*433d6423SLionel Sambuc }
109*433d6423SLionel Sambuc return(0);
110*433d6423SLionel Sambuc }
111*433d6423SLionel Sambuc
112*433d6423SLionel Sambuc quit();
113*433d6423SLionel Sambuc return(-1);
114*433d6423SLionel Sambuc }
115