1*653f037eSmartin /* $NetBSD: t_access.c,v 1.3 2019/07/16 17:29:18 martin Exp $ */
2068fb4f1Sjruoho
3068fb4f1Sjruoho /*-
4068fb4f1Sjruoho * Copyright (c) 2011 The NetBSD Foundation, Inc.
5068fb4f1Sjruoho * All rights reserved.
6068fb4f1Sjruoho *
7068fb4f1Sjruoho * This code is derived from software contributed to The NetBSD Foundation
8068fb4f1Sjruoho * by Jukka Ruohonen.
9068fb4f1Sjruoho *
10068fb4f1Sjruoho * Redistribution and use in source and binary forms, with or without
11068fb4f1Sjruoho * modification, are permitted provided that the following conditions
12068fb4f1Sjruoho * are met:
13068fb4f1Sjruoho * 1. Redistributions of source code must retain the above copyright
14068fb4f1Sjruoho * notice, this list of conditions and the following disclaimer.
15068fb4f1Sjruoho * 2. Redistributions in binary form must reproduce the above copyright
16068fb4f1Sjruoho * notice, this list of conditions and the following disclaimer in the
17068fb4f1Sjruoho * documentation and/or other materials provided with the distribution.
18068fb4f1Sjruoho *
19068fb4f1Sjruoho * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20068fb4f1Sjruoho * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21068fb4f1Sjruoho * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22068fb4f1Sjruoho * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23068fb4f1Sjruoho * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24068fb4f1Sjruoho * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25068fb4f1Sjruoho * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26068fb4f1Sjruoho * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27068fb4f1Sjruoho * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28068fb4f1Sjruoho * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29068fb4f1Sjruoho * POSSIBILITY OF SUCH DAMAGE.
30068fb4f1Sjruoho */
31068fb4f1Sjruoho #include <sys/cdefs.h>
32*653f037eSmartin __RCSID("$NetBSD: t_access.c,v 1.3 2019/07/16 17:29:18 martin Exp $");
3325f1087aSchristos
3425f1087aSchristos #include <atf-c.h>
3525f1087aSchristos
3625f1087aSchristos #include <sys/stat.h>
37068fb4f1Sjruoho
38068fb4f1Sjruoho #include <errno.h>
39068fb4f1Sjruoho #include <fcntl.h>
40068fb4f1Sjruoho #include <limits.h>
41068fb4f1Sjruoho #include <stdint.h>
42068fb4f1Sjruoho #include <stdlib.h>
43068fb4f1Sjruoho #include <unistd.h>
44068fb4f1Sjruoho
45068fb4f1Sjruoho static const char path[] = "access";
46068fb4f1Sjruoho static const int mode[4] = { R_OK, W_OK, X_OK, F_OK };
47068fb4f1Sjruoho
48068fb4f1Sjruoho ATF_TC_WITH_CLEANUP(access_access);
ATF_TC_HEAD(access_access,tc)49068fb4f1Sjruoho ATF_TC_HEAD(access_access, tc)
50068fb4f1Sjruoho {
51068fb4f1Sjruoho atf_tc_set_md_var(tc, "descr", "Test access(2) for EACCES");
52068fb4f1Sjruoho atf_tc_set_md_var(tc, "require.user", "unprivileged");
53068fb4f1Sjruoho }
54068fb4f1Sjruoho
ATF_TC_BODY(access_access,tc)55068fb4f1Sjruoho ATF_TC_BODY(access_access, tc)
56068fb4f1Sjruoho {
57068fb4f1Sjruoho const int perm[3] = { 0200, 0400, 0000 };
58068fb4f1Sjruoho size_t i;
59068fb4f1Sjruoho int fd;
60068fb4f1Sjruoho
61*653f037eSmartin fd = open(path, O_RDONLY | O_CREAT, 0600);
62068fb4f1Sjruoho
63068fb4f1Sjruoho if (fd < 0)
64068fb4f1Sjruoho return;
65068fb4f1Sjruoho
66068fb4f1Sjruoho for (i = 0; i < __arraycount(mode) - 1; i++) {
67068fb4f1Sjruoho
68068fb4f1Sjruoho ATF_REQUIRE(fchmod(fd, perm[i]) == 0);
69068fb4f1Sjruoho
70068fb4f1Sjruoho errno = 0;
71068fb4f1Sjruoho
72068fb4f1Sjruoho ATF_REQUIRE(access(path, mode[i]) != 0);
73068fb4f1Sjruoho ATF_REQUIRE(errno == EACCES);
74068fb4f1Sjruoho }
75068fb4f1Sjruoho
76068fb4f1Sjruoho ATF_REQUIRE(close(fd) == 0);
77068fb4f1Sjruoho }
78068fb4f1Sjruoho
ATF_TC_CLEANUP(access_access,tc)79068fb4f1Sjruoho ATF_TC_CLEANUP(access_access, tc)
80068fb4f1Sjruoho {
81068fb4f1Sjruoho (void)unlink(path);
82068fb4f1Sjruoho }
83068fb4f1Sjruoho
84068fb4f1Sjruoho ATF_TC(access_fault);
ATF_TC_HEAD(access_fault,tc)85068fb4f1Sjruoho ATF_TC_HEAD(access_fault, tc)
86068fb4f1Sjruoho {
87068fb4f1Sjruoho atf_tc_set_md_var(tc, "descr", "Test access(2) for EFAULT");
88068fb4f1Sjruoho }
89068fb4f1Sjruoho
ATF_TC_BODY(access_fault,tc)90068fb4f1Sjruoho ATF_TC_BODY(access_fault, tc)
91068fb4f1Sjruoho {
92068fb4f1Sjruoho size_t i;
93068fb4f1Sjruoho
94068fb4f1Sjruoho for (i = 0; i < __arraycount(mode); i++) {
95068fb4f1Sjruoho
96068fb4f1Sjruoho errno = 0;
97068fb4f1Sjruoho
98068fb4f1Sjruoho ATF_REQUIRE(access(NULL, mode[i]) != 0);
99068fb4f1Sjruoho ATF_REQUIRE(errno == EFAULT);
100068fb4f1Sjruoho
101068fb4f1Sjruoho errno = 0;
102068fb4f1Sjruoho
103068fb4f1Sjruoho ATF_REQUIRE(access((char *)-1, mode[i]) != 0);
104068fb4f1Sjruoho ATF_REQUIRE(errno == EFAULT);
105068fb4f1Sjruoho }
106068fb4f1Sjruoho }
107068fb4f1Sjruoho
108068fb4f1Sjruoho ATF_TC(access_inval);
ATF_TC_HEAD(access_inval,tc)109068fb4f1Sjruoho ATF_TC_HEAD(access_inval, tc)
110068fb4f1Sjruoho {
111068fb4f1Sjruoho atf_tc_set_md_var(tc, "descr", "Test access(2) for EINVAL");
112068fb4f1Sjruoho }
113068fb4f1Sjruoho
ATF_TC_BODY(access_inval,tc)114068fb4f1Sjruoho ATF_TC_BODY(access_inval, tc)
115068fb4f1Sjruoho {
116068fb4f1Sjruoho
117068fb4f1Sjruoho errno = 0;
118068fb4f1Sjruoho
119068fb4f1Sjruoho ATF_REQUIRE(access("/usr", -1) != 0);
120068fb4f1Sjruoho ATF_REQUIRE(errno == EINVAL);
121068fb4f1Sjruoho }
122068fb4f1Sjruoho
123068fb4f1Sjruoho ATF_TC(access_notdir);
ATF_TC_HEAD(access_notdir,tc)124068fb4f1Sjruoho ATF_TC_HEAD(access_notdir, tc)
125068fb4f1Sjruoho {
126068fb4f1Sjruoho atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOTDIR");
127068fb4f1Sjruoho }
128068fb4f1Sjruoho
ATF_TC_BODY(access_notdir,tc)129068fb4f1Sjruoho ATF_TC_BODY(access_notdir, tc)
130068fb4f1Sjruoho {
131068fb4f1Sjruoho size_t i;
132068fb4f1Sjruoho
133068fb4f1Sjruoho for (i = 0; i < __arraycount(mode); i++) {
134068fb4f1Sjruoho
135068fb4f1Sjruoho errno = 0;
136068fb4f1Sjruoho
137068fb4f1Sjruoho /*
138068fb4f1Sjruoho * IEEE Std 1003.1-2008 about ENOTDIR:
139068fb4f1Sjruoho *
140068fb4f1Sjruoho * "A component of the path prefix is not a directory,
141068fb4f1Sjruoho * or the path argument contains at least one non-<slash>
142068fb4f1Sjruoho * character and ends with one or more trailing <slash>
143068fb4f1Sjruoho * characters and the last pathname component names an
144068fb4f1Sjruoho * existing file that is neither a directory nor a symbolic
145068fb4f1Sjruoho * link to a directory."
146068fb4f1Sjruoho */
147068fb4f1Sjruoho ATF_REQUIRE(access("/etc/passwd//", mode[i]) != 0);
148068fb4f1Sjruoho ATF_REQUIRE(errno == ENOTDIR);
149068fb4f1Sjruoho }
150068fb4f1Sjruoho }
151068fb4f1Sjruoho
152068fb4f1Sjruoho ATF_TC(access_notexist);
ATF_TC_HEAD(access_notexist,tc)153068fb4f1Sjruoho ATF_TC_HEAD(access_notexist, tc)
154068fb4f1Sjruoho {
155068fb4f1Sjruoho atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOENT");
156068fb4f1Sjruoho }
157068fb4f1Sjruoho
ATF_TC_BODY(access_notexist,tc)158068fb4f1Sjruoho ATF_TC_BODY(access_notexist, tc)
159068fb4f1Sjruoho {
160068fb4f1Sjruoho size_t i;
161068fb4f1Sjruoho
162068fb4f1Sjruoho for (i = 0; i < __arraycount(mode); i++) {
163068fb4f1Sjruoho
164068fb4f1Sjruoho errno = 0;
165068fb4f1Sjruoho
166068fb4f1Sjruoho ATF_REQUIRE(access("", mode[i]) != 0);
167068fb4f1Sjruoho ATF_REQUIRE(errno == ENOENT);
168068fb4f1Sjruoho }
169068fb4f1Sjruoho }
170068fb4f1Sjruoho
171068fb4f1Sjruoho ATF_TC(access_toolong);
ATF_TC_HEAD(access_toolong,tc)172068fb4f1Sjruoho ATF_TC_HEAD(access_toolong, tc)
173068fb4f1Sjruoho {
174068fb4f1Sjruoho atf_tc_set_md_var(tc, "descr", "Test access(2) for ENAMETOOLONG");
175068fb4f1Sjruoho }
176068fb4f1Sjruoho
ATF_TC_BODY(access_toolong,tc)177068fb4f1Sjruoho ATF_TC_BODY(access_toolong, tc)
178068fb4f1Sjruoho {
179068fb4f1Sjruoho char *buf;
180068fb4f1Sjruoho size_t i;
181068fb4f1Sjruoho
182068fb4f1Sjruoho buf = malloc(PATH_MAX);
183068fb4f1Sjruoho
184068fb4f1Sjruoho if (buf == NULL)
185068fb4f1Sjruoho return;
186068fb4f1Sjruoho
187068fb4f1Sjruoho for (i = 0; i < PATH_MAX; i++)
188068fb4f1Sjruoho buf[i] = 'x';
189068fb4f1Sjruoho
190068fb4f1Sjruoho for (i = 0; i < __arraycount(mode); i++) {
191068fb4f1Sjruoho
192068fb4f1Sjruoho errno = 0;
193068fb4f1Sjruoho
194068fb4f1Sjruoho ATF_REQUIRE(access(buf, mode[i]) != 0);
195068fb4f1Sjruoho ATF_REQUIRE(errno == ENAMETOOLONG);
196068fb4f1Sjruoho }
197068fb4f1Sjruoho
198068fb4f1Sjruoho free(buf);
199068fb4f1Sjruoho }
200068fb4f1Sjruoho
ATF_TP_ADD_TCS(tp)201068fb4f1Sjruoho ATF_TP_ADD_TCS(tp)
202068fb4f1Sjruoho {
203068fb4f1Sjruoho
204068fb4f1Sjruoho ATF_TP_ADD_TC(tp, access_access);
205068fb4f1Sjruoho ATF_TP_ADD_TC(tp, access_fault);
206068fb4f1Sjruoho ATF_TP_ADD_TC(tp, access_inval);
207068fb4f1Sjruoho ATF_TP_ADD_TC(tp, access_notdir);
208068fb4f1Sjruoho ATF_TP_ADD_TC(tp, access_notexist);
209068fb4f1Sjruoho ATF_TP_ADD_TC(tp, access_toolong);
210068fb4f1Sjruoho
211068fb4f1Sjruoho return atf_no_error();
212068fb4f1Sjruoho }
213