1 /* 2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. 3 * AUTHOR : Richard Logan 4 * CO-PILOT : William Roske 5 * Copyright (c) 2014 Cyril Hrubis <chrubis (at) suse.cz> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of version 2 of the GNU General Public License as 9 * published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it would be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 * 15 * Further, this software is distributed without any warranty that it is 16 * free of the rightful claim of any third person regarding infringement 17 * or the like. Any license provided herein, whether implied or 18 * otherwise, applies only to this software file. Patent licenses, if 19 * any, provided herein do not apply to combinations of this program with 20 * other software, or any other product whatsoever. 21 * 22 * You should have received a copy of the GNU General Public License along 23 * with this program; if not, write the Free Software Foundation, Inc., 24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 25 * 26 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 27 * Mountain View, CA 94043, or: 28 * 29 * http://www.sgi.com 30 * 31 * For further information regarding this notice, see: 32 * 33 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ 34 * 35 */ 36 37 /* 38 * Negative test cases for link(2). 39 * 40 * This test program should contain test cases where link will fail regardless 41 * of who executed it (i.e. joe-user or root) 42 */ 43 #include <sys/types.h> 44 #include <fcntl.h> 45 #include <sys/stat.h> 46 #include <errno.h> 47 #include <string.h> 48 #include <signal.h> 49 #include <sys/param.h> 50 #include <sys/mman.h> 51 #include "test.h" 52 #include "safe_macros.h" 53 54 static char *bad_addr = 0; 55 56 static char longpath[PATH_MAX + 2]; 57 #if !defined(UCLINUX) 58 char high_addr[64]; 59 #endif 60 61 struct test_case_t { 62 char *file1; 63 char *desc1; 64 char *file2; 65 char *desc2; 66 int exp_errno; 67 } test_cases[] = { 68 /* first path is invalid */ 69 {"nonexistfile", "non-existent file", "nefile", "nefile", ENOENT}, 70 {"", "path is empty string", "nefile", "nefile", ENOENT}, 71 {"neefile/file", "path contains a non-existent file", "nefile", 72 "nefile", ENOENT}, 73 {"regfile/file", "path contains a regular file", "nefile", "nefile", 74 ENOTDIR}, 75 {longpath, "pathname too long", "nefile", "nefile", ENAMETOOLONG}, 76 #if !defined(UCLINUX) 77 {high_addr, "address beyond address space", "nefile", "nefile", EFAULT}, 78 #endif 79 {(char *)-1, "negative address", "nefile", "nefile", EFAULT}, 80 /* second path is invalid */ 81 {"regfile", "regfile", "", "empty string", ENOENT}, 82 {"regfile", "regfile", "neefile/file", 83 "path contains a non-existent file", ENOENT}, 84 {"regfile", "regfile", "file/file", 85 "path contains a regular file", ENOENT}, 86 {"regfile", "regfile", longpath, "pathname too long", ENAMETOOLONG}, 87 #if !defined(UCLINUX) 88 {"regfile", "regfile", high_addr, 89 "address beyond address space", EFAULT}, 90 #endif 91 {"regfile", "regfile", (char *)-1, "negative address", EFAULT}, 92 /* two existing files */ 93 {"regfile", "regfile", "regfile2", "regfile2", EEXIST}, 94 }; 95 96 char *TCID = "link04"; 97 int TST_TOTAL = ARRAY_SIZE(test_cases); 98 99 static void setup(void); 100 static void cleanup(void); 101 102 int main(int ac, char **av) 103 { 104 int lc; 105 char *fname1, *fname2; 106 char *desc1, *desc2; 107 int i; 108 109 tst_parse_opts(ac, av, NULL, NULL); 110 111 setup(); 112 113 for (lc = 0; TEST_LOOPING(lc); lc++) { 114 115 tst_count = 0; 116 117 for (i = 0; i < TST_TOTAL; i++) { 118 119 fname1 = test_cases[i].file1; 120 desc1 = test_cases[i].desc1; 121 fname2 = test_cases[i].file2; 122 desc2 = test_cases[i].desc2; 123 124 #if !defined(UCLINUX) 125 if (fname1 == high_addr) 126 fname1 = get_high_address(); 127 128 if (fname2 == high_addr) 129 fname2 = get_high_address(); 130 #endif 131 132 TEST(link(fname1, fname2)); 133 134 if (TEST_RETURN == -1) { 135 if (TEST_ERRNO == test_cases[i].exp_errno) { 136 tst_resm(TPASS | TTERRNO, 137 "link(<%s>, <%s>)", 138 desc1, desc2); 139 } else { 140 tst_resm(TFAIL | TTERRNO, 141 "link(<%s>, <%s>) Failed " 142 "expected errno: %d", 143 desc1, desc2, 144 test_cases[i].exp_errno); 145 } 146 } else { 147 tst_resm(TFAIL, 148 "link(<%s>, <%s>) returned %ld, " 149 "expected -1, errno:%d", 150 desc1, desc2, TEST_RETURN, 151 test_cases[i].exp_errno); 152 } 153 } 154 155 } 156 157 cleanup(); 158 tst_exit(); 159 } 160 161 static void setup(void) 162 { 163 tst_sig(NOFORK, DEF_HANDLER, cleanup); 164 165 TEST_PAUSE; 166 167 tst_tmpdir(); 168 169 #if !defined(UCLINUX) 170 bad_addr = SAFE_MMAP(cleanup, 0, 1, PROT_NONE, 171 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0); 172 test_cases[6].file1 = bad_addr; 173 test_cases[12].file2 = bad_addr; 174 #endif 175 176 memset(longpath, 'a', PATH_MAX+1); 177 SAFE_TOUCH(cleanup, "regfile", 0777, NULL); 178 SAFE_TOUCH(cleanup, "regfile2", 0777, NULL); 179 SAFE_MKDIR(cleanup, "dir", 0777); 180 } 181 182 static void cleanup(void) 183 { 184 tst_rmdir(); 185 } 186