1 /* 2 * Copyright (c) International Business Machines Corp., 2001 3 * Ported by Wayne Boyer 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 /* 21 * DESCRIPTION 22 * Testcase to check creat(2) sets the following errnos correctly: 23 * 1. EISDIR 24 * 2. ENAMETOOLONG 25 * 3. ENOENT 26 * 4. ENOTDIR 27 * 5. EFAULT 28 * 6. EACCES 29 * 7. ELOOP 30 * 8. EROFS 31 * 32 * 33 * ALGORITHM 34 * 1. Attempt to creat(2) an existing directory, and test for 35 * EISDIR 36 * 2. Attempt to creat(2) a file whose name is more than 37 * VFS_MAXNAMLEN and test for ENAMETOOLONG. 38 * 3. Attempt to creat(2) a file inside a directory which doesn't 39 * exist, and test for ENOENT 40 * 4. Attempt to creat(2) a file, the pathname of which comprises 41 * a component which is a file, test for ENOTDIR. 42 * 5. Attempt to creat(2) a file with a bad address 43 * and test for EFAULT 44 * 6. Attempt to creat(2) a file in a directory with no 45 * execute permission and test for EACCES 46 * 7. Attempt to creat(2) a file which links the other file that 47 * links the former and test for ELOOP 48 * 8. Attempt to creat(2) a file in a Read-only file system 49 * and test for EROFS 50 */ 51 52 #include <errno.h> 53 #include <string.h> 54 #include <limits.h> 55 #include <pwd.h> 56 #include <sys/mman.h> 57 #include <sys/types.h> 58 #include <sys/stat.h> 59 #include <sys/mount.h> 60 61 #include "tst_test.h" 62 63 #define TEST_FILE "test_dir" 64 #define NO_DIR "testfile/testdir" 65 #define NOT_DIR "file1/testdir" 66 #define TEST6_FILE "dir6/file6" 67 #define TEST7_FILE "file7" 68 #define TEST8_FILE "mntpoint/tmp" 69 70 #define MODE1 0444 71 #define MODE2 0666 72 73 static void setup(void); 74 static void test6_setup(void); 75 static void test6_cleanup(void); 76 #if !defined(UCLINUX) 77 static void bad_addr_setup(int); 78 #endif 79 80 static struct passwd *ltpuser; 81 static char long_name[PATH_MAX+2]; 82 83 static struct test_case_t { 84 char *fname; 85 int mode; 86 int error; 87 void (*setup)(); 88 void (*cleanup)(void); 89 } tcases[] = { 90 {TEST_FILE, MODE1, EISDIR, NULL, NULL}, 91 {long_name, MODE1, ENAMETOOLONG, NULL, NULL}, 92 {NO_DIR, MODE1, ENOENT, NULL, NULL}, 93 {NOT_DIR, MODE1, ENOTDIR, NULL, NULL}, 94 #if !defined(UCLINUX) 95 {NULL, MODE1, EFAULT, bad_addr_setup, NULL}, 96 #endif 97 {TEST6_FILE, MODE1, EACCES, test6_setup, test6_cleanup}, 98 {TEST7_FILE, MODE1, ELOOP, NULL, NULL}, 99 {TEST8_FILE, MODE1, EROFS, NULL, NULL}, 100 }; 101 102 static void verify_creat(unsigned int i) 103 { 104 if (tcases[i].setup != NULL) 105 tcases[i].setup(i); 106 107 TEST(creat(tcases[i].fname, tcases[i].mode)); 108 109 if (tcases[i].cleanup != NULL) 110 tcases[i].cleanup(); 111 112 if (TEST_RETURN != -1) { 113 tst_res(TFAIL, "call succeeded unexpectedly"); 114 return; 115 } 116 117 if (TEST_ERRNO == tcases[i].error) { 118 tst_res(TPASS | TTERRNO, "got expected failure"); 119 return; 120 } 121 122 tst_res(TFAIL | TTERRNO, "expected %s", 123 tst_strerrno(tcases[i].error)); 124 } 125 126 127 static void setup(void) 128 { 129 ltpuser = SAFE_GETPWNAM("nobody"); 130 131 SAFE_MKDIR(TEST_FILE, MODE2); 132 133 memset(long_name, 'a', PATH_MAX+1); 134 135 SAFE_TOUCH("file1", MODE1, NULL); 136 137 SAFE_MKDIR("dir6", MODE2); 138 139 SAFE_SYMLINK(TEST7_FILE, "test_file_eloop2"); 140 SAFE_SYMLINK("test_file_eloop2", TEST7_FILE); 141 } 142 143 #if !defined(UCLINUX) 144 static void bad_addr_setup(int i) 145 { 146 if (tcases[i].fname) 147 return; 148 149 tcases[i].fname = SAFE_MMAP(0, 1, PROT_NONE, 150 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 151 } 152 #endif 153 154 static void test6_setup(void) 155 { 156 SAFE_SETEUID(ltpuser->pw_uid); 157 } 158 159 static void test6_cleanup(void) 160 { 161 SAFE_SETEUID(0); 162 } 163 164 static struct tst_test test = { 165 .tcnt = ARRAY_SIZE(tcases), 166 .test = verify_creat, 167 .needs_root = 1, 168 .needs_rofs = 1, 169 .needs_tmpdir = 1, 170 .mntpoint = "mntpoint", 171 .setup = setup, 172 }; 173