1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 3f08c3bdfSopenharmony_ci * 4f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify 5f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by 6f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 7f08c3bdfSopenharmony_ci * (at your option) any later version. 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful, 10f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12f08c3bdfSopenharmony_ci * the GNU General Public License for more details. 13f08c3bdfSopenharmony_ci * 14f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 15f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software 16f08c3bdfSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17f08c3bdfSopenharmony_ci */ 18f08c3bdfSopenharmony_ci 19f08c3bdfSopenharmony_ci/* 20f08c3bdfSopenharmony_ci * NAME 21f08c3bdfSopenharmony_ci * mprotect03.c 22f08c3bdfSopenharmony_ci * 23f08c3bdfSopenharmony_ci * DESCRIPTION 24f08c3bdfSopenharmony_ci * Testcase to check the mprotect(2) system call. 25f08c3bdfSopenharmony_ci * 26f08c3bdfSopenharmony_ci * ALGORITHM 27f08c3bdfSopenharmony_ci * Create a shared mapped file region with PROT_READ | PROT_WRITE 28f08c3bdfSopenharmony_ci * using the mmap(2) call. Then, use mprotect(2) to disable the 29f08c3bdfSopenharmony_ci * write permission on the mapped region. Then, attempt to write to 30f08c3bdfSopenharmony_ci * the mapped region using memcpy(). This would generate a sigsegv. 31f08c3bdfSopenharmony_ci * Since the sigsegv is generated, this needs to be done in a child 32f08c3bdfSopenharmony_ci * process (as sigsegv would repeatedly be generated). The testcase 33f08c3bdfSopenharmony_ci * succeeds only when this sigsegv is generated while attempting to 34f08c3bdfSopenharmony_ci * memcpy() on a shared region with only read permission. 35f08c3bdfSopenharmony_ci * 36f08c3bdfSopenharmony_ci * HISTORY 37f08c3bdfSopenharmony_ci * 07/2001 Ported by Wayne Boyer 38f08c3bdfSopenharmony_ci * 05/2002 changed over to use tst_sig instead of sigaction 39f08c3bdfSopenharmony_ci */ 40f08c3bdfSopenharmony_ci 41f08c3bdfSopenharmony_ci#include <errno.h> 42f08c3bdfSopenharmony_ci#include <fcntl.h> 43f08c3bdfSopenharmony_ci#include <sys/mman.h> 44f08c3bdfSopenharmony_ci#include <limits.h> 45f08c3bdfSopenharmony_ci#include <signal.h> 46f08c3bdfSopenharmony_ci#include <sys/wait.h> 47f08c3bdfSopenharmony_ci#include "test.h" 48f08c3bdfSopenharmony_ci 49f08c3bdfSopenharmony_ci#include "safe_macros.h" 50f08c3bdfSopenharmony_ci 51f08c3bdfSopenharmony_ci#ifndef PAGESIZE 52f08c3bdfSopenharmony_ci#define PAGESIZE 4096 53f08c3bdfSopenharmony_ci#endif 54f08c3bdfSopenharmony_ci#define FAILED 1 55f08c3bdfSopenharmony_ci 56f08c3bdfSopenharmony_cistatic void cleanup(void); 57f08c3bdfSopenharmony_cistatic void setup(void); 58f08c3bdfSopenharmony_ci 59f08c3bdfSopenharmony_cichar *TCID = "mprotect03"; 60f08c3bdfSopenharmony_ciint TST_TOTAL = 1; 61f08c3bdfSopenharmony_ciint status; 62f08c3bdfSopenharmony_cichar file1[BUFSIZ]; 63f08c3bdfSopenharmony_ci 64f08c3bdfSopenharmony_ciint main(int ac, char **av) 65f08c3bdfSopenharmony_ci{ 66f08c3bdfSopenharmony_ci int lc; 67f08c3bdfSopenharmony_ci 68f08c3bdfSopenharmony_ci char *addr; 69f08c3bdfSopenharmony_ci int fd, pid; 70f08c3bdfSopenharmony_ci char *buf = "abcdefghijklmnopqrstuvwxyz"; 71f08c3bdfSopenharmony_ci 72f08c3bdfSopenharmony_ci tst_parse_opts(ac, av, NULL, NULL); 73f08c3bdfSopenharmony_ci 74f08c3bdfSopenharmony_ci setup(); 75f08c3bdfSopenharmony_ci 76f08c3bdfSopenharmony_ci for (lc = 0; TEST_LOOPING(lc); lc++) { 77f08c3bdfSopenharmony_ci tst_count = 0; 78f08c3bdfSopenharmony_ci 79f08c3bdfSopenharmony_ci if ((fd = open(file1, O_RDWR | O_CREAT, 0777)) < 0) 80f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, "open failed"); 81f08c3bdfSopenharmony_ci 82f08c3bdfSopenharmony_ci SAFE_WRITE(cleanup, SAFE_WRITE_ALL, fd, buf, strlen(buf)); 83f08c3bdfSopenharmony_ci 84f08c3bdfSopenharmony_ci /* 85f08c3bdfSopenharmony_ci * mmap the PAGESIZE bytes as read only. 86f08c3bdfSopenharmony_ci */ 87f08c3bdfSopenharmony_ci addr = mmap(0, strlen(buf), PROT_READ | PROT_WRITE, MAP_SHARED, 88f08c3bdfSopenharmony_ci fd, 0); 89f08c3bdfSopenharmony_ci if (addr == MAP_FAILED) 90f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, "mmap failed"); 91f08c3bdfSopenharmony_ci 92f08c3bdfSopenharmony_ci /* 93f08c3bdfSopenharmony_ci * Try to change the protection to WRITE. 94f08c3bdfSopenharmony_ci */ 95f08c3bdfSopenharmony_ci TEST(mprotect(addr, strlen(buf), PROT_READ)); 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci if (TEST_RETURN != -1) { 98f08c3bdfSopenharmony_ci if ((pid = FORK_OR_VFORK()) == -1) { 99f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, "fork failed"); 100f08c3bdfSopenharmony_ci } 101f08c3bdfSopenharmony_ci 102f08c3bdfSopenharmony_ci if (pid == 0) { 103f08c3bdfSopenharmony_ci memcpy(addr, buf, strlen(buf)); 104f08c3bdfSopenharmony_ci tst_resm(TINFO, "memcpy() did " 105f08c3bdfSopenharmony_ci "not generate SIGSEGV"); 106f08c3bdfSopenharmony_ci exit(1); 107f08c3bdfSopenharmony_ci } 108f08c3bdfSopenharmony_ci 109f08c3bdfSopenharmony_ci waitpid(pid, &status, 0); 110f08c3bdfSopenharmony_ci if (WEXITSTATUS(status) != 0) { 111f08c3bdfSopenharmony_ci tst_resm(TFAIL, "child returned " 112f08c3bdfSopenharmony_ci "unexpected status"); 113f08c3bdfSopenharmony_ci } else { 114f08c3bdfSopenharmony_ci tst_resm(TPASS, "SIGSEGV generated " 115f08c3bdfSopenharmony_ci "as expected"); 116f08c3bdfSopenharmony_ci } 117f08c3bdfSopenharmony_ci } else { 118f08c3bdfSopenharmony_ci tst_resm(TFAIL, "mprotect failed " 119f08c3bdfSopenharmony_ci "unexpectedly, errno: %d", errno); 120f08c3bdfSopenharmony_ci } 121f08c3bdfSopenharmony_ci 122f08c3bdfSopenharmony_ci /* clean up things in case we are looping */ 123f08c3bdfSopenharmony_ci SAFE_MUNMAP(cleanup, addr, strlen(buf)); 124f08c3bdfSopenharmony_ci SAFE_CLOSE(cleanup, fd); 125f08c3bdfSopenharmony_ci SAFE_UNLINK(cleanup, file1); 126f08c3bdfSopenharmony_ci } 127f08c3bdfSopenharmony_ci 128f08c3bdfSopenharmony_ci cleanup(); 129f08c3bdfSopenharmony_ci tst_exit(); 130f08c3bdfSopenharmony_ci} 131f08c3bdfSopenharmony_ci 132f08c3bdfSopenharmony_cistatic void sighandler(int sig) 133f08c3bdfSopenharmony_ci{ 134f08c3bdfSopenharmony_ci if (sig == SIGSEGV) { 135f08c3bdfSopenharmony_ci tst_resm(TINFO, "received signal: SIGSEGV"); 136f08c3bdfSopenharmony_ci tst_exit(); 137f08c3bdfSopenharmony_ci } else 138f08c3bdfSopenharmony_ci tst_brkm(TBROK, 0, "Unexpected signal %d received.", sig); 139f08c3bdfSopenharmony_ci} 140f08c3bdfSopenharmony_ci 141f08c3bdfSopenharmony_cistatic void setup(void) 142f08c3bdfSopenharmony_ci{ 143f08c3bdfSopenharmony_ci tst_sig(FORK, sighandler, NULL); 144f08c3bdfSopenharmony_ci 145f08c3bdfSopenharmony_ci TEST_PAUSE; 146f08c3bdfSopenharmony_ci 147f08c3bdfSopenharmony_ci tst_tmpdir(); 148f08c3bdfSopenharmony_ci 149f08c3bdfSopenharmony_ci sprintf(file1, "mprotect03.tmp.%d", getpid()); 150f08c3bdfSopenharmony_ci} 151f08c3bdfSopenharmony_ci 152f08c3bdfSopenharmony_cistatic void cleanup(void) 153f08c3bdfSopenharmony_ci{ 154f08c3bdfSopenharmony_ci tst_rmdir(); 155f08c3bdfSopenharmony_ci} 156