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