• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <errno.h>
13 #include <fcntl.h>
14 #include <pwd.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18 #include <sys/mount.h>
19 
20 #include "tst_test.h"
21 
22 #define DIR_MODE	(S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP| \
23 			 S_IXGRP|S_IROTH|S_IXOTH)
24 #define FILE_EISDIR		"."
25 #define FILE_EACCES		"/dev/null"
26 #define FILE_ENOENT		"/tmp/does/not/exist"
27 #define FILE_ENOTDIR		"./tmpfile/"
28 #define TEST_TMPFILE		"./tmpfile"
29 #define TEST_ELOOP		"test_file_eloop1"
30 #define TEST_ENAMETOOLONG	nametoolong
31 #define TEST_EROFS		"mntpoint/file"
32 
33 static char nametoolong[PATH_MAX+2];
34 static struct passwd *ltpuser;
35 
setup_euid(void)36 static void setup_euid(void)
37 {
38 	SAFE_SETEUID(ltpuser->pw_uid);
39 }
40 
cleanup_euid(void)41 static void cleanup_euid(void)
42 {
43 	SAFE_SETEUID(0);
44 }
45 
46 static struct test_case {
47 	char *filename;
48 	char *exp_errval;
49 	int exp_errno;
50 	void (*setupfunc) ();
51 	void (*cleanfunc) ();
52 } tcases[] = {
53 	{FILE_EISDIR, "EISDIR",  EISDIR,  NULL,   NULL},
54 	{FILE_EACCES, "EACCES",  EACCES,  NULL,   NULL},
55 	{FILE_ENOENT, "ENOENT",  ENOENT,  NULL,   NULL},
56 	{FILE_ENOTDIR, "ENOTDIR", ENOTDIR, NULL,   NULL},
57 	{TEST_TMPFILE, "EPERM",   EPERM,   setup_euid, cleanup_euid},
58 	{NULL,       "EPERM",   EPERM,   setup_euid, cleanup_euid},
59 	{TEST_ELOOP, "ELOOP",        ELOOP,        NULL, NULL},
60 	{TEST_ENAMETOOLONG, "ENAMETOOLONG", ENAMETOOLONG, NULL, NULL},
61 	{TEST_EROFS, "EROFS",        EROFS,        NULL, NULL},
62 };
63 
setup(void)64 static void setup(void)
65 {
66 	int fd;
67 
68 	TEST(acct(NULL));
69 	if (TST_RET == -1 && TST_ERR == ENOSYS)
70 		tst_brk(TCONF, "acct() system call isn't configured in kernel");
71 
72 	ltpuser = SAFE_GETPWNAM("nobody");
73 
74 	fd = SAFE_CREAT(TEST_TMPFILE, 0777);
75 	SAFE_CLOSE(fd);
76 
77 	TEST(acct(TEST_TMPFILE));
78 	if (TST_RET == -1)
79 		tst_brk(TBROK | TTERRNO, "acct failed unexpectedly");
80 
81 	/* turn off acct, so we are in a known state */
82 	TEST(acct(NULL));
83 	if (TST_RET == -1)
84 		tst_brk(TBROK | TTERRNO, "acct(NULL) failed");
85 
86 	/* ELOOP SETTING */
87 	SAFE_SYMLINK(TEST_ELOOP, "test_file_eloop2");
88 	SAFE_SYMLINK("test_file_eloop2", TEST_ELOOP);
89 
90 	/* ENAMETOOLONG SETTING */
91 	memset(nametoolong, 'a', PATH_MAX+1);
92 }
93 
verify_acct(unsigned int nr)94 static void verify_acct(unsigned int nr)
95 {
96 	struct test_case *tcase = &tcases[nr];
97 
98 	if (tcase->setupfunc)
99 		tcase->setupfunc();
100 
101 	TEST(acct(tcase->filename));
102 
103 	if (tcase->cleanfunc)
104 		tcase->cleanfunc();
105 
106 	if (TST_RET != -1) {
107 		tst_res(TFAIL, "acct(%s) succeeded unexpectedly",
108 				tcase->filename);
109 		return;
110 	}
111 
112 	if (TST_ERR == tcase->exp_errno) {
113 		tst_res(TPASS | TTERRNO, "acct() failed as expected");
114 	} else {
115 		tst_res(TFAIL | TTERRNO,
116 				"acct() failed, expected: %s",
117 				tst_strerrno(tcase->exp_errno));
118 	}
119 }
120 
121 static struct tst_test test = {
122 	.needs_root = 1,
123 	.mntpoint = "mntpoint",
124 	.needs_rofs = 1,
125 	.tcnt = ARRAY_SIZE(tcases),
126 	.setup = setup,
127 	.test = verify_acct,
128 };
129