18329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI/* 28329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * Copyright (c) 2013 FNST, DAN LI <li.dan@cn.fujitsu.com> 38329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * 48329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * This program is free software; you can redistribute it and/or modify 58329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * it under the terms of the GNU General Public License as published by 68329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * the Free Software Foundation; either version 2 of the License, or 78329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * (at your option) any later version. 88329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * 98329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * This program is distributed in the hope that it will be useful, 108329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * but WITHOUT ANY WARRANTY; without even the implied warranty of 118329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 128329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * the GNU General Public License for more details. 138329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * 148329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * You should have received a copy of the GNU General Public License 158329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * along with this program; if not, write to the Free Software 168329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 178329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI */ 188329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 198329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI/* 208329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * Test Description: 218329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * Verify error signal SIGBUS. 228329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * "Attempted access to a portion of the buffer that does not correspond 238329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * to the file." 248329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * 258329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * Expected Result: 268329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * mmap() should succeed returning the address of the mapped region, 278329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * and an attempt to access the memory which does not correspond to the file 288329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * should rise the signal SIGBUS. 298329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI */ 308329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI#include <stdio.h> 318329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI#include <stdlib.h> 328329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI#include <sys/types.h> 338329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI#include <errno.h> 348329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI#include <unistd.h> 358329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI#include <fcntl.h> 368329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI#include <string.h> 378329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI#include <signal.h> 388329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI#include <sys/stat.h> 398329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI#include <sys/mman.h> 408329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI#include <setjmp.h> 418329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 428329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI#include "test.h" 438329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 448329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI#define TEMPFILE "mmapfile" 458329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 468329ed8a449efe34672eabfe6ab44bf7116cc661DAN LIchar *TCID = "mmap13"; 478329ed8a449efe34672eabfe6ab44bf7116cc661DAN LIint TST_TOTAL = 1; 488329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 498329ed8a449efe34672eabfe6ab44bf7116cc661DAN LIstatic size_t page_sz; 508329ed8a449efe34672eabfe6ab44bf7116cc661DAN LIstatic char *addr; 518329ed8a449efe34672eabfe6ab44bf7116cc661DAN LIstatic int fildes; 528329ed8a449efe34672eabfe6ab44bf7116cc661DAN LIstatic volatile sig_atomic_t pass; 538329ed8a449efe34672eabfe6ab44bf7116cc661DAN LIstatic sigjmp_buf env; 548329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 558329ed8a449efe34672eabfe6ab44bf7116cc661DAN LIstatic void setup(void); 568329ed8a449efe34672eabfe6ab44bf7116cc661DAN LIstatic void cleanup(void); 578329ed8a449efe34672eabfe6ab44bf7116cc661DAN LIstatic void sig_handler(int sig); 588329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 598329ed8a449efe34672eabfe6ab44bf7116cc661DAN LIint main(int argc, char *argv[]) 608329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI{ 618329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI int lc; 628329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI char *ch; 638329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 64d6d11d08678aac1ed2c370ea8e42e5f45aea07beCyril Hrubis tst_parse_opts(argc, argv, NULL, NULL); 658329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 668329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI setup(); 678329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 688329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI for (lc = 0; TEST_LOOPING(lc); lc++) { 698329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI tst_count = 0; 708329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 718329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI addr = mmap(NULL, page_sz * 2, PROT_READ | PROT_WRITE, 728329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI MAP_FILE | MAP_SHARED, fildes, 0); 738329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 748329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI if (addr == MAP_FAILED) { 758329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI tst_resm(TFAIL | TERRNO, "mmap() failed on %s", 768329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI TEMPFILE); 778329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI continue; 788329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI } 798329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 80e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis if (sigsetjmp(env, 1) == 0) { 81e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis ch = addr + page_sz + 1; 82e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis *ch = 0; 838329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI } 848329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 85e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis if (pass) 86e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis tst_resm(TPASS, "Got SIGBUS " 87e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis "as expected"); 88e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis else 89e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis tst_resm(TFAIL, "Invalid access not " 90e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis "rise SIGBUS"); 91e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis 928329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI if (munmap(addr, page_sz * 2) != 0) 938329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI tst_brkm(TFAIL | TERRNO, cleanup, 948329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI "failed to unmap the mmapped pages"); 958329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 968329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI pass = 0; 978329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI } 988329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 998329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI cleanup(); 1008329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI tst_exit(); 1018329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI} 1028329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 1038329ed8a449efe34672eabfe6ab44bf7116cc661DAN LIstatic void setup(void) 1048329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI{ 1058329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI tst_sig(NOFORK, sig_handler, cleanup); 1068329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 1078329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI TEST_PAUSE; 1088329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 1098329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI page_sz = getpagesize(); 1108329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 1118329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI tst_tmpdir(); 1128329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 1138329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0766); 1148329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI if (fildes < 0) 1158329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI tst_brkm(TFAIL | TERRNO, cleanup, "opening %s failed", 1168329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI TEMPFILE); 1178329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 1188329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI if (ftruncate(fildes, page_sz / 2) == -1) 1198329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI tst_brkm(TFAIL | TERRNO, cleanup, "ftruncate %s failed", 1208329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI TEMPFILE); 1218329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI} 1228329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 1238329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI/* 1248329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * This function gets executed when the test process receives 1258329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * the signal SIGBUS while trying to access the memory which 1268329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI * does not correspond to the file. 1278329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI */ 1288329ed8a449efe34672eabfe6ab44bf7116cc661DAN LIstatic void sig_handler(int sig) 1298329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI{ 1308329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI if (sig == SIGBUS) { 1318329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI pass = 1; 1328329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI siglongjmp(env, 1); 1338329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI } else { 1348329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI tst_brkm(TBROK, cleanup, "received an unexpected signal"); 1358329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI } 1368329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI} 1378329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI 1388329ed8a449efe34672eabfe6ab44bf7116cc661DAN LIstatic void cleanup(void) 1398329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI{ 1408329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI close(fildes); 1418329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI tst_rmdir(); 1428329ed8a449efe34672eabfe6ab44bf7116cc661DAN LI} 143