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