1// SPDX-License-Identifier: GPL-2.0-or-later 2 3/* 4 * Copyright (c) International Business Machines Corp., 2002 5 */ 6 7/* 12/03/2002 Port to LTP robbiew@us.ibm.com */ 8/* 06/30/2001 Port to Linux nsharoff@us.ibm.com */ 9 10/*\ 11 * [DOCUMENTATION] 12 * Verify that acct() returns proper errno on failure. 13 */ 14 15#include <sys/types.h> 16#include <sys/stat.h> 17#include <errno.h> 18#include <fcntl.h> 19#include <pwd.h> 20#include <stdio.h> 21#include <stdlib.h> 22#include <unistd.h> 23#include <sys/mount.h> 24 25#include "tst_test.h" 26 27#define DIR_MODE (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP| \ 28 S_IXGRP|S_IROTH|S_IXOTH) 29#define FILE_EISDIR "." 30#define FILE_EACCESS "/dev/null" 31#define FILE_ENOENT "/tmp/does/not/exist" 32#define FILE_ENOTDIR "./tmpfile/" 33#define FILE_TMPFILE "./tmpfile" 34#define FILE_ELOOP "test_file_eloop1" 35#define FILE_EROFS "ro_mntpoint/file" 36 37static struct passwd *ltpuser; 38 39static char *file_eisdir; 40static char *file_eaccess; 41static char *file_enoent; 42static char *file_enotdir; 43static char *file_tmpfile; 44static char *file_eloop; 45static char *file_enametoolong; 46static char *file_erofs; 47static char *file_null; 48 49static void setup_euid(void) 50{ 51 SAFE_SETEUID(ltpuser->pw_uid); 52} 53 54static void cleanup_euid(void) 55{ 56 SAFE_SETEUID(0); 57} 58 59static struct test_case { 60 char **filename; 61 char *desc; 62 int exp_errno; 63 void (*setupfunc) (); 64 void (*cleanfunc) (); 65} tcases[] = { 66 {&file_eisdir, FILE_EISDIR, EISDIR, NULL, NULL}, 67 {&file_eaccess, FILE_EACCESS, EACCES, NULL, NULL}, 68 {&file_enoent, FILE_ENOENT, ENOENT, NULL, NULL}, 69 {&file_enotdir, FILE_ENOTDIR, ENOTDIR, NULL, NULL}, 70 {&file_tmpfile, FILE_TMPFILE, EPERM, setup_euid, cleanup_euid}, 71 {&file_null, "NULL", EPERM, setup_euid, cleanup_euid}, 72 {&file_eloop, FILE_ELOOP, ELOOP, NULL, NULL}, 73 {&file_enametoolong, "aaaa...", ENAMETOOLONG, NULL, NULL}, 74 {&file_erofs, FILE_EROFS, EROFS, NULL, NULL}, 75}; 76 77static void setup(void) 78{ 79 int fd; 80 81 TEST(acct(NULL)); 82 if (TST_RET == -1 && TST_ERR == ENOSYS) 83 tst_brk(TCONF, "acct() system call isn't configured in kernel"); 84 85 ltpuser = SAFE_GETPWNAM("nobody"); 86 87 fd = SAFE_CREAT(FILE_TMPFILE, 0777); 88 SAFE_CLOSE(fd); 89 90 TEST(acct(FILE_TMPFILE)); 91 if (TST_RET == -1) 92 tst_brk(TBROK | TTERRNO, "acct failed unexpectedly"); 93 94 /* turn off acct, so we are in a known state */ 95 TEST(acct(NULL)); 96 if (TST_RET == -1) 97 tst_brk(TBROK | TTERRNO, "acct(NULL) failed"); 98 99 /* ELOOP SETTING */ 100 SAFE_SYMLINK(FILE_ELOOP, "test_file_eloop2"); 101 SAFE_SYMLINK("test_file_eloop2", FILE_ELOOP); 102 103 memset(file_enametoolong, 'a', PATH_MAX+1); 104 file_enametoolong[PATH_MAX+1] = 0; 105} 106 107static void verify_acct(unsigned int nr) 108{ 109 struct test_case *tcase = &tcases[nr]; 110 111 if (tcase->setupfunc) 112 tcase->setupfunc(); 113 114 TST_EXP_FAIL(acct(*tcase->filename), tcase->exp_errno, 115 "acct(%s)", tcase->desc); 116 117 if (tcase->cleanfunc) 118 tcase->cleanfunc(); 119} 120 121static struct tst_test test = { 122 .needs_root = 1, 123 .mntpoint = "ro_mntpoint", 124 .needs_rofs = 1, 125 .tcnt = ARRAY_SIZE(tcases), 126 .setup = setup, 127 .test = verify_acct, 128 .bufs = (struct tst_buffers []) { 129 {&file_eisdir, .str = FILE_EISDIR}, 130 {&file_eaccess, .str = FILE_EACCESS}, 131 {&file_enoent, .str = FILE_ENOENT}, 132 {&file_enotdir, .str = FILE_ENOTDIR}, 133 {&file_tmpfile, .str = FILE_TMPFILE}, 134 {&file_eloop, .str = FILE_ELOOP}, 135 {&file_enametoolong, .size = PATH_MAX+2}, 136 {&file_erofs, .str = FILE_EROFS}, 137 {} 138 } 139}; 140