1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 4f08c3bdfSopenharmony_ci * Ported to LTP: Wayne Boyer 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci 7f08c3bdfSopenharmony_ci/* 8f08c3bdfSopenharmony_ci * DESCRIPTION 9f08c3bdfSopenharmony_ci * Testcase to check creat(2) sets the following errnos correctly: 10f08c3bdfSopenharmony_ci * 1. EISDIR 11f08c3bdfSopenharmony_ci * 2. ENAMETOOLONG 12f08c3bdfSopenharmony_ci * 3. ENOENT 13f08c3bdfSopenharmony_ci * 4. ENOTDIR 14f08c3bdfSopenharmony_ci * 5. EFAULT 15f08c3bdfSopenharmony_ci * 6. EACCES 16f08c3bdfSopenharmony_ci * 7. ELOOP 17f08c3bdfSopenharmony_ci * 8. EROFS 18f08c3bdfSopenharmony_ci * 19f08c3bdfSopenharmony_ci * 20f08c3bdfSopenharmony_ci * ALGORITHM 21f08c3bdfSopenharmony_ci * 1. Attempt to creat(2) an existing directory, and test for 22f08c3bdfSopenharmony_ci * EISDIR 23f08c3bdfSopenharmony_ci * 2. Attempt to creat(2) a file whose name is more than 24f08c3bdfSopenharmony_ci * VFS_MAXNAMLEN and test for ENAMETOOLONG. 25f08c3bdfSopenharmony_ci * 3. Attempt to creat(2) a file inside a directory which doesn't 26f08c3bdfSopenharmony_ci * exist, and test for ENOENT 27f08c3bdfSopenharmony_ci * 4. Attempt to creat(2) a file, the pathname of which comprises 28f08c3bdfSopenharmony_ci * a component which is a file, test for ENOTDIR. 29f08c3bdfSopenharmony_ci * 5. Attempt to creat(2) a file with a bad address 30f08c3bdfSopenharmony_ci * and test for EFAULT 31f08c3bdfSopenharmony_ci * 6. Attempt to creat(2) a file in a directory with no 32f08c3bdfSopenharmony_ci * execute permission and test for EACCES 33f08c3bdfSopenharmony_ci * 7. Attempt to creat(2) a file which links the other file that 34f08c3bdfSopenharmony_ci * links the former and test for ELOOP 35f08c3bdfSopenharmony_ci * 8. Attempt to creat(2) a file in a Read-only file system 36f08c3bdfSopenharmony_ci * and test for EROFS 37f08c3bdfSopenharmony_ci */ 38f08c3bdfSopenharmony_ci 39f08c3bdfSopenharmony_ci#include <errno.h> 40f08c3bdfSopenharmony_ci#include <string.h> 41f08c3bdfSopenharmony_ci#include <limits.h> 42f08c3bdfSopenharmony_ci#include <pwd.h> 43f08c3bdfSopenharmony_ci#include <sys/mman.h> 44f08c3bdfSopenharmony_ci#include <sys/types.h> 45f08c3bdfSopenharmony_ci#include <sys/stat.h> 46f08c3bdfSopenharmony_ci#include <sys/mount.h> 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_ci#include "tst_test.h" 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_ci#define TEST_FILE "test_dir" 51f08c3bdfSopenharmony_ci#define NO_DIR "testfile/testdir" 52f08c3bdfSopenharmony_ci#define NOT_DIR "file1/testdir" 53f08c3bdfSopenharmony_ci#define TEST6_FILE "dir6/file6" 54f08c3bdfSopenharmony_ci#define TEST7_FILE "file7" 55f08c3bdfSopenharmony_ci#define TEST8_FILE "mntpoint/tmp" 56f08c3bdfSopenharmony_ci 57f08c3bdfSopenharmony_ci#define MODE1 0444 58f08c3bdfSopenharmony_ci#define MODE2 0666 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_cistatic void setup(void); 61f08c3bdfSopenharmony_cistatic void test6_setup(void); 62f08c3bdfSopenharmony_cistatic void test6_cleanup(void); 63f08c3bdfSopenharmony_ci#if !defined(UCLINUX) 64f08c3bdfSopenharmony_cistatic void bad_addr_setup(int); 65f08c3bdfSopenharmony_ci#endif 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_cistatic struct passwd *ltpuser; 68f08c3bdfSopenharmony_cistatic char long_name[PATH_MAX+2]; 69f08c3bdfSopenharmony_ci 70f08c3bdfSopenharmony_cistatic struct test_case_t { 71f08c3bdfSopenharmony_ci char *fname; 72f08c3bdfSopenharmony_ci int mode; 73f08c3bdfSopenharmony_ci int error; 74f08c3bdfSopenharmony_ci void (*setup)(); 75f08c3bdfSopenharmony_ci void (*cleanup)(void); 76f08c3bdfSopenharmony_ci} tcases[] = { 77f08c3bdfSopenharmony_ci {TEST_FILE, MODE1, EISDIR, NULL, NULL}, 78f08c3bdfSopenharmony_ci {long_name, MODE1, ENAMETOOLONG, NULL, NULL}, 79f08c3bdfSopenharmony_ci {NO_DIR, MODE1, ENOENT, NULL, NULL}, 80f08c3bdfSopenharmony_ci {NOT_DIR, MODE1, ENOTDIR, NULL, NULL}, 81f08c3bdfSopenharmony_ci#if !defined(UCLINUX) 82f08c3bdfSopenharmony_ci {NULL, MODE1, EFAULT, bad_addr_setup, NULL}, 83f08c3bdfSopenharmony_ci#endif 84f08c3bdfSopenharmony_ci {TEST6_FILE, MODE1, EACCES, test6_setup, test6_cleanup}, 85f08c3bdfSopenharmony_ci {TEST7_FILE, MODE1, ELOOP, NULL, NULL}, 86f08c3bdfSopenharmony_ci {TEST8_FILE, MODE1, EROFS, NULL, NULL}, 87f08c3bdfSopenharmony_ci}; 88f08c3bdfSopenharmony_ci 89f08c3bdfSopenharmony_cistatic void verify_creat(unsigned int i) 90f08c3bdfSopenharmony_ci{ 91f08c3bdfSopenharmony_ci if (tcases[i].setup != NULL) 92f08c3bdfSopenharmony_ci tcases[i].setup(i); 93f08c3bdfSopenharmony_ci 94f08c3bdfSopenharmony_ci TEST(creat(tcases[i].fname, tcases[i].mode)); 95f08c3bdfSopenharmony_ci 96f08c3bdfSopenharmony_ci if (tcases[i].cleanup != NULL) 97f08c3bdfSopenharmony_ci tcases[i].cleanup(); 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_ci if (TST_RET != -1) { 100f08c3bdfSopenharmony_ci tst_res(TFAIL, "call succeeded unexpectedly"); 101f08c3bdfSopenharmony_ci return; 102f08c3bdfSopenharmony_ci } 103f08c3bdfSopenharmony_ci 104f08c3bdfSopenharmony_ci if (TST_ERR == tcases[i].error) { 105f08c3bdfSopenharmony_ci tst_res(TPASS | TTERRNO, "got expected failure"); 106f08c3bdfSopenharmony_ci return; 107f08c3bdfSopenharmony_ci } 108f08c3bdfSopenharmony_ci 109f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "expected %s", 110f08c3bdfSopenharmony_ci tst_strerrno(tcases[i].error)); 111f08c3bdfSopenharmony_ci} 112f08c3bdfSopenharmony_ci 113f08c3bdfSopenharmony_ci 114f08c3bdfSopenharmony_cistatic void setup(void) 115f08c3bdfSopenharmony_ci{ 116f08c3bdfSopenharmony_ci ltpuser = SAFE_GETPWNAM("nobody"); 117f08c3bdfSopenharmony_ci 118f08c3bdfSopenharmony_ci SAFE_MKDIR(TEST_FILE, MODE2); 119f08c3bdfSopenharmony_ci 120f08c3bdfSopenharmony_ci memset(long_name, 'a', PATH_MAX+1); 121f08c3bdfSopenharmony_ci 122f08c3bdfSopenharmony_ci SAFE_TOUCH("file1", MODE1, NULL); 123f08c3bdfSopenharmony_ci 124f08c3bdfSopenharmony_ci SAFE_MKDIR("dir6", MODE2); 125f08c3bdfSopenharmony_ci 126f08c3bdfSopenharmony_ci SAFE_SYMLINK(TEST7_FILE, "test_file_eloop2"); 127f08c3bdfSopenharmony_ci SAFE_SYMLINK("test_file_eloop2", TEST7_FILE); 128f08c3bdfSopenharmony_ci} 129f08c3bdfSopenharmony_ci 130f08c3bdfSopenharmony_ci#if !defined(UCLINUX) 131f08c3bdfSopenharmony_cistatic void bad_addr_setup(int i) 132f08c3bdfSopenharmony_ci{ 133f08c3bdfSopenharmony_ci if (tcases[i].fname) 134f08c3bdfSopenharmony_ci return; 135f08c3bdfSopenharmony_ci 136f08c3bdfSopenharmony_ci tcases[i].fname = SAFE_MMAP(0, 1, PROT_NONE, 137f08c3bdfSopenharmony_ci MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 138f08c3bdfSopenharmony_ci} 139f08c3bdfSopenharmony_ci#endif 140f08c3bdfSopenharmony_ci 141f08c3bdfSopenharmony_cistatic void test6_setup(void) 142f08c3bdfSopenharmony_ci{ 143f08c3bdfSopenharmony_ci SAFE_SETEUID(ltpuser->pw_uid); 144f08c3bdfSopenharmony_ci} 145f08c3bdfSopenharmony_ci 146f08c3bdfSopenharmony_cistatic void test6_cleanup(void) 147f08c3bdfSopenharmony_ci{ 148f08c3bdfSopenharmony_ci SAFE_SETEUID(0); 149f08c3bdfSopenharmony_ci} 150f08c3bdfSopenharmony_ci 151f08c3bdfSopenharmony_cistatic struct tst_test test = { 152f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(tcases), 153f08c3bdfSopenharmony_ci .test = verify_creat, 154f08c3bdfSopenharmony_ci .needs_root = 1, 155f08c3bdfSopenharmony_ci .needs_rofs = 1, 156f08c3bdfSopenharmony_ci .mntpoint = "mntpoint", 157f08c3bdfSopenharmony_ci .setup = setup, 158f08c3bdfSopenharmony_ci}; 159