1*cf9621edSriastradh /* $NetBSD: t_fcntl.c,v 1.4 2023/08/05 08:05:16 riastradh Exp $ */
20a76d2edSchristos
30a76d2edSchristos /*-
40a76d2edSchristos * Copyright (c) 2019 The NetBSD Foundation, Inc.
50a76d2edSchristos * All rights reserved.
60a76d2edSchristos *
70a76d2edSchristos * This code is derived from software contributed to The NetBSD Foundation
80a76d2edSchristos * by Christos Zoulas.
90a76d2edSchristos *
100a76d2edSchristos * Redistribution and use in source and binary forms, with or without
110a76d2edSchristos * modification, are permitted provided that the following conditions
120a76d2edSchristos * are met:
130a76d2edSchristos * 1. Redistributions of source code must retain the above copyright
140a76d2edSchristos * notice, this list of conditions and the following disclaimer.
150a76d2edSchristos * 2. Redistributions in binary form must reproduce the above copyright
160a76d2edSchristos * notice, this list of conditions and the following disclaimer in the
170a76d2edSchristos * documentation and/or other materials provided with the distribution.
180a76d2edSchristos *
190a76d2edSchristos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
200a76d2edSchristos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
210a76d2edSchristos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
220a76d2edSchristos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
230a76d2edSchristos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
240a76d2edSchristos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
250a76d2edSchristos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
260a76d2edSchristos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
270a76d2edSchristos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
280a76d2edSchristos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
290a76d2edSchristos * POSSIBILITY OF SUCH DAMAGE.
300a76d2edSchristos */
310a76d2edSchristos
320a76d2edSchristos #include <sys/param.h>
330a76d2edSchristos #include <sys/types.h>
34d3ba7ba3Schristos #include <sys/mman.h>
350a76d2edSchristos #include <atf-c.h>
360a76d2edSchristos #include <fcntl.h>
370a76d2edSchristos #include <errno.h>
380a76d2edSchristos #include <stdlib.h>
390a76d2edSchristos #include <string.h>
400a76d2edSchristos #include <unistd.h>
410a76d2edSchristos
42d3ba7ba3Schristos ATF_TC(getpath_vnode);
ATF_TC_HEAD(getpath_vnode,tc)43d3ba7ba3Schristos ATF_TC_HEAD(getpath_vnode, tc)
440a76d2edSchristos {
450a76d2edSchristos
46d3ba7ba3Schristos atf_tc_set_md_var(tc, "descr", "Checks fcntl(2) F_GETPATH for vnodes");
470a76d2edSchristos }
480a76d2edSchristos
490a76d2edSchristos static const struct {
500a76d2edSchristos const char *name;
510a76d2edSchristos int rv;
520a76d2edSchristos } files[] = {
530a76d2edSchristos { "/bin/ls", 0 },
540a76d2edSchristos { "/bin/sh", 0 },
550a76d2edSchristos { "/dev/zero", 0 },
560a76d2edSchristos { "/dev/null", 0 },
57d35ed14fSchristos { "/sbin/chown", 0 },
580a76d2edSchristos { "/", ENOENT },
590a76d2edSchristos };
600a76d2edSchristos
ATF_TC_BODY(getpath_vnode,tc)61d3ba7ba3Schristos ATF_TC_BODY(getpath_vnode, tc)
620a76d2edSchristos {
630a76d2edSchristos char path[MAXPATHLEN];
640a76d2edSchristos int fd, rv;
650a76d2edSchristos
660a76d2edSchristos for (size_t i = 0; i < __arraycount(files); i++) {
670a76d2edSchristos fd = open(files[i].name, O_RDONLY|O_NOFOLLOW);
68d35ed14fSchristos ATF_REQUIRE_MSG(fd != -1, "Cannot open `%s'", files[i].name);
690a76d2edSchristos rv = fcntl(fd, F_GETPATH, path);
700a76d2edSchristos if (files[i].rv) {
710a76d2edSchristos ATF_REQUIRE_MSG(errno == files[i].rv,
720a76d2edSchristos "Unexpected error %d != %d for `%s'", errno,
730a76d2edSchristos files[i].rv, files[i].name);
740a76d2edSchristos } else {
750a76d2edSchristos ATF_REQUIRE_MSG(rv != -1,
760a76d2edSchristos "Can't get path for `%s' (%s)", files[i].name,
770a76d2edSchristos strerror(errno));
780a76d2edSchristos ATF_REQUIRE_MSG(strcmp(files[i].name, path) == 0,
790a76d2edSchristos "Bad name `%s' != `%s'", path, files[i].name);
800a76d2edSchristos close(fd);
810a76d2edSchristos }
820a76d2edSchristos }
830a76d2edSchristos }
840a76d2edSchristos
85d3ba7ba3Schristos ATF_TC(getpath_memfd);
ATF_TC_HEAD(getpath_memfd,tc)86d3ba7ba3Schristos ATF_TC_HEAD(getpath_memfd, tc)
87d3ba7ba3Schristos {
88d3ba7ba3Schristos
89d3ba7ba3Schristos atf_tc_set_md_var(tc, "descr",
90d3ba7ba3Schristos "Checks fcntl(2) F_GETPATH for fds created by memfd_create");
91d3ba7ba3Schristos }
92d3ba7ba3Schristos
93d3ba7ba3Schristos #define MEMFD_NAME(name) { name, "memfd:" name }
94d3ba7ba3Schristos static const struct {
95d3ba7ba3Schristos const char *bare;
96d3ba7ba3Schristos const char *prefixed;
97d3ba7ba3Schristos } memfd_names[] = {
98d3ba7ba3Schristos MEMFD_NAME(""),
99d3ba7ba3Schristos MEMFD_NAME("some text"),
100d3ba7ba3Schristos MEMFD_NAME("memfd:"),
101d3ba7ba3Schristos MEMFD_NAME("../\\"),
102d3ba7ba3Schristos };
103d3ba7ba3Schristos
ATF_TC_BODY(getpath_memfd,tc)104d3ba7ba3Schristos ATF_TC_BODY(getpath_memfd, tc)
105d3ba7ba3Schristos {
106d3ba7ba3Schristos char path[MAXPATHLEN];
107d3ba7ba3Schristos int fd, rv;
108d3ba7ba3Schristos
109d3ba7ba3Schristos for (size_t i = 0; i < __arraycount(memfd_names); i++) {
110d3ba7ba3Schristos fd = memfd_create(memfd_names[i].bare, 0);
111*cf9621edSriastradh ATF_CHECK_MSG(fd != -1, "Failed to create memfd (%s)",
112d3ba7ba3Schristos strerror(errno));
113*cf9621edSriastradh if (fd == -1)
114*cf9621edSriastradh continue;
115d3ba7ba3Schristos rv = fcntl(fd, F_GETPATH, path);
116*cf9621edSriastradh ATF_CHECK_MSG(rv != -1, "Can't get path `%s' (%s)",
117d3ba7ba3Schristos memfd_names[i].bare, strerror(errno));
118*cf9621edSriastradh if (rv == -1)
119*cf9621edSriastradh goto next;
120*cf9621edSriastradh ATF_CHECK_MSG(strcmp(memfd_names[i].prefixed, path) == 0,
121d3ba7ba3Schristos "Bad name `%s' != `%s'", path, memfd_names[i].prefixed);
122*cf9621edSriastradh next: close(fd);
123d3ba7ba3Schristos }
124d3ba7ba3Schristos }
125d3ba7ba3Schristos
ATF_TP_ADD_TCS(tp)1260a76d2edSchristos ATF_TP_ADD_TCS(tp)
1270a76d2edSchristos {
128d3ba7ba3Schristos ATF_TP_ADD_TC(tp, getpath_vnode);
129d3ba7ba3Schristos ATF_TP_ADD_TC(tp, getpath_memfd);
1300a76d2edSchristos
1310a76d2edSchristos return atf_no_error();
1320a76d2edSchristos }
133