1 /**
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #define _GNU_SOURCE
17 #include <fcntl.h>
18 #include <pthread.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <sys/mman.h>
22 #include <sys/types.h>
23 #include <sys/uio.h>
24 #include <sys/wait.h>
25 #include <unistd.h>
26 #include "../includes/common.h"
27 
28 #define BUFS 256
29 #define IOV_LEN 16
30 #define MAGIC 7
31 
32 int fd[2];
33 struct iovec *iovs = NULL;
34 
func_evil(void * data)35 void *func_evil(void *data) {
36   munmap((void *)(0x45678000), PAGE_SIZE);
37   mmap((void *)(0x45678000), PAGE_SIZE, PROT_READ | PROT_WRITE,
38        MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
39   return data;
40 }
41 
func_readv(void * data)42 void *func_readv(void *data) {
43   readv(fd[0], iovs, BUFS);
44   return data;
45 }
46 
main()47 int main() {
48   int ret = -1, i;
49   void *bufs[BUFS];
50   time_t test_started = start_timer();
51   pthread_t thr_evil, thr_readv;
52 
53   if (pipe(fd) < 0) {
54     goto __out;
55   }
56   fcntl(fd[0], F_SETFL, O_NONBLOCK);
57   fcntl(fd[1], F_SETFL, O_NONBLOCK);
58 
59   iovs = (struct iovec *)malloc(sizeof(bufs) / sizeof(bufs[0]) *
60                                 sizeof(struct iovec));
61   if (iovs == NULL) {
62     goto __close_pipe;
63   }
64 
65   bufs[MAGIC] = mmap((void *)(0x45678000), PAGE_SIZE, PROT_READ | PROT_WRITE,
66                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
67   if (bufs[MAGIC] == MAP_FAILED) {
68     goto __close_pipe;
69   }
70 
71   for (size_t i = 0; i < sizeof(bufs) / sizeof(bufs[0]); i++) {
72     if (i == MAGIC) continue;
73     bufs[i] = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
74                    MAP_SHARED | MAP_ANONYMOUS, -1, 0);
75     if (bufs[i] == MAP_FAILED) {
76       goto __free_bufs;
77     }
78 
79     iovs[i].iov_base = bufs[i];
80     iovs[i].iov_len = IOV_LEN;
81   }
82 
83   iovs[MAGIC - 1].iov_len = IOV_LEN * 10;
84   iovs[MAGIC].iov_base = bufs[MAGIC];
85   iovs[MAGIC].iov_len = IOV_LEN;
86 
87   i = 0;
88 
89   while (timer_active(test_started)) {
90     write(fd[1], bufs[0], PAGE_SIZE);
91 
92     pthread_create(&thr_evil, NULL, func_evil, NULL);
93     pthread_create(&thr_readv, NULL, func_readv, NULL);
94 
95     pthread_join(thr_evil, NULL);
96     pthread_join(thr_readv, NULL);
97   }
98 
99 __free_bufs:
100   for (size_t i = 0; i < sizeof(bufs) / sizeof(bufs[0]); i++) {
101     if (bufs[i]) munmap(bufs[i], PAGE_SIZE);
102   }
103 
104 __close_pipe:
105   close(fd[0]);
106   close(fd[1]);
107 
108 __out:
109   return ret;
110 
111   return 0;
112 }
113