• 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 /*\
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 
37 static struct passwd *ltpuser;
38 
39 static char *file_eisdir;
40 static char *file_eaccess;
41 static char *file_enoent;
42 static char *file_enotdir;
43 static char *file_tmpfile;
44 static char *file_eloop;
45 static char *file_enametoolong;
46 static char *file_erofs;
47 static char *file_null;
48 
setup_euid(void)49 static void setup_euid(void)
50 {
51 	SAFE_SETEUID(ltpuser->pw_uid);
52 }
53 
cleanup_euid(void)54 static void cleanup_euid(void)
55 {
56 	SAFE_SETEUID(0);
57 }
58 
59 static 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 
setup(void)77 static 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 
verify_acct(unsigned int nr)107 static 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 
121 static 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