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   const size_t page_size = getpagesize();
37   munmap((void *)(0x45678000), page_size);
38   mmap((void *)(0x45678000), page_size, PROT_READ | PROT_WRITE,
39        MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
40   return data;
41 }
42 
func_readv(void * data)43 void *func_readv(void *data) {
44   readv(fd[0], iovs, BUFS);
45   return data;
46 }
47 
main()48 int main() {
49   const size_t page_size = getpagesize();
50   int ret = -1, i;
51   void *bufs[BUFS];
52   time_t test_started = start_timer();
53   pthread_t thr_evil, thr_readv;
54 
55   if (pipe(fd) < 0) {
56     goto __out;
57   }
58   fcntl(fd[0], F_SETFL, O_NONBLOCK);
59   fcntl(fd[1], F_SETFL, O_NONBLOCK);
60 
61   iovs = (struct iovec *)malloc(sizeof(bufs) / sizeof(bufs[0]) *
62                                 sizeof(struct iovec));
63   if (iovs == NULL) {
64     goto __close_pipe;
65   }
66 
67   bufs[MAGIC] = mmap((void *)(0x45678000), page_size, PROT_READ | PROT_WRITE,
68                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
69   if (bufs[MAGIC] == MAP_FAILED) {
70     goto __close_pipe;
71   }
72 
73   for (size_t i = 0; i < sizeof(bufs) / sizeof(bufs[0]); i++) {
74     if (i == MAGIC) continue;
75     bufs[i] = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
76                    MAP_SHARED | MAP_ANONYMOUS, -1, 0);
77     if (bufs[i] == MAP_FAILED) {
78       goto __free_bufs;
79     }
80 
81     iovs[i].iov_base = bufs[i];
82     iovs[i].iov_len = IOV_LEN;
83   }
84 
85   iovs[MAGIC - 1].iov_len = IOV_LEN * 10;
86   iovs[MAGIC].iov_base = bufs[MAGIC];
87   iovs[MAGIC].iov_len = IOV_LEN;
88 
89   i = 0;
90 
91   while (timer_active(test_started)) {
92     write(fd[1], bufs[0], page_size);
93 
94     pthread_create(&thr_evil, NULL, func_evil, NULL);
95     pthread_create(&thr_readv, NULL, func_readv, NULL);
96 
97     pthread_join(thr_evil, NULL);
98     pthread_join(thr_readv, NULL);
99   }
100 
101 __free_bufs:
102   for (size_t i = 0; i < sizeof(bufs) / sizeof(bufs[0]); i++) {
103     if (bufs[i]) munmap(bufs[i], page_size);
104   }
105 
106 __close_pipe:
107   close(fd[0]);
108   close(fd[1]);
109 
110 __out:
111   return ret;
112 
113   return 0;
114 }
115