aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2021-05-04 12:56:31 +0000
committerMark Johnston <markj@FreeBSD.org>2021-05-04 12:56:31 +0000
commitb59851e99c20f3a72c34bdf9919e3bf49b894e4e (patch)
treec06d3443b23ccf71c3383384baa2d7f4e1bb876a
parent8bde6d15d1fa9a947c2bdc5eddae36cfbb1076dc (diff)
downloadsrc-b59851e99c20f3a72c34bdf9919e3bf49b894e4e.tar.gz
src-b59851e99c20f3a72c34bdf9919e3bf49b894e4e.zip
path_test: Add a few new test cases
MFC after: 1 week Sponsored by: The FreeBSD Foundation
-rw-r--r--tests/sys/file/path_test.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/tests/sys/file/path_test.c b/tests/sys/file/path_test.c
index a8354f88b091..e1f5240374c4 100644
--- a/tests/sys/file/path_test.c
+++ b/tests/sys/file/path_test.c
@@ -38,10 +38,12 @@
#include <sys/ioctl.h>
#include <sys/memrange.h>
#include <sys/mman.h>
+#include <sys/ptrace.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/uio.h>
+#include <sys/un.h>
#include <sys/wait.h>
#include <aio.h>
@@ -49,6 +51,7 @@
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -205,6 +208,47 @@ ATF_TC_BODY(path_capsicum, tc)
waitchild(child, 4);
}
+/* Make sure that ptrace(PT_COREDUMP) cannot be used to write to a path fd. */
+ATF_TC_WITHOUT_HEAD(path_coredump);
+ATF_TC_BODY(path_coredump, tc)
+{
+ char path[PATH_MAX];
+ struct ptrace_coredump pc;
+ int error, pathfd, status;
+ pid_t child;
+
+ mktdir(path, "path_coredump.XXXXXX");
+
+ child = fork();
+ ATF_REQUIRE_MSG(child != -1, FMT_ERR("fork"));
+ if (child == 0) {
+ while (true)
+ (void)sleep(1);
+ }
+
+ pathfd = open(path, O_PATH);
+ ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
+
+ error = ptrace(PT_ATTACH, child, 0, 0);
+ ATF_REQUIRE_MSG(error == 0, FMT_ERR("ptrace"));
+ error = waitpid(child, &status, 0);
+ ATF_REQUIRE_MSG(error != -1, FMT_ERR("waitpid"));
+ ATF_REQUIRE_MSG(WIFSTOPPED(status), "unexpected status %d", status);
+
+ pc.pc_fd = pathfd;
+ pc.pc_flags = 0;
+ pc.pc_limit = 0;
+ error = ptrace(PT_COREDUMP, child, (void *)&pc, sizeof(pc));
+ ATF_REQUIRE_ERRNO(EBADF, error == -1);
+
+ error = ptrace(PT_DETACH, child, 0, 0);
+ ATF_REQUIRE_MSG(error == 0, FMT_ERR("ptrace"));
+
+ ATF_REQUIRE_MSG(kill(child, SIGKILL) == 0, FMT_ERR("kill"));
+
+ CHECKED_CLOSE(pathfd);
+}
+
/* Verify operations on directory path descriptors. */
ATF_TC_WITHOUT_HEAD(path_directory);
ATF_TC_BODY(path_directory, tc)
@@ -506,6 +550,33 @@ ATF_TC_BODY(path_fexecve, tc)
ATF_REQUIRE_ERRNO(EACCES, pathfd < 0);
}
+/* Make sure that O_PATH restrictions apply to named pipes as well. */
+ATF_TC_WITHOUT_HEAD(path_fifo);
+ATF_TC_BODY(path_fifo, tc)
+{
+ char path[PATH_MAX], buf[BUFSIZ];
+ struct kevent ev;
+ int kq, pathfd;
+
+ snprintf(path, sizeof(path), "path_fifo.XXXXXX");
+ ATF_REQUIRE_MSG(mktemp(path) == path, FMT_ERR("mktemp"));
+
+ ATF_REQUIRE_MSG(mkfifo(path, 0666) == 0, FMT_ERR("mkfifo"));
+
+ pathfd = open(path, O_PATH);
+ ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
+ memset(buf, 0, sizeof(buf));
+ ATF_REQUIRE_ERRNO(EBADF, write(pathfd, buf, sizeof(buf)));
+ ATF_REQUIRE_ERRNO(EBADF, read(pathfd, buf, sizeof(buf)));
+
+ kq = kqueue();
+ ATF_REQUIRE_MSG(kq >= 0, FMT_ERR("kqueue"));
+ EV_SET(&ev, pathfd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
+ ATF_REQUIRE_ERRNO(EBADF, kevent(kq, &ev, 1, NULL, 0, NULL) == -1);
+
+ CHECKED_CLOSE(pathfd);
+}
+
/* Files may be unlinked using a path fd. */
ATF_TC_WITHOUT_HEAD(path_funlinkat);
ATF_TC_BODY(path_funlinkat, tc)
@@ -755,11 +826,38 @@ ATF_TC_BODY(path_rights, tc)
CHECKED_CLOSE(sd[1]);
}
+/* Verify that a local socket can't be opened with O_PATH. */
+ATF_TC_WITHOUT_HEAD(path_unix);
+ATF_TC_BODY(path_unix, tc)
+{
+ char path[PATH_MAX];
+ struct sockaddr_un sun;
+ int pathfd, sd;
+
+ snprintf(path, sizeof(path), "path_unix.XXXXXX");
+ ATF_REQUIRE_MSG(mktemp(path) == path, FMT_ERR("mktemp"));
+
+ sd = socket(PF_LOCAL, SOCK_STREAM, 0);
+ ATF_REQUIRE_MSG(sd >= 0, FMT_ERR("socket"));
+
+ memset(&sun, 0, sizeof(sun));
+ sun.sun_family = PF_LOCAL;
+ (void)strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
+ ATF_REQUIRE_MSG(bind(sd, (struct sockaddr *)&sun, SUN_LEN(&sun)) == 0,
+ FMT_ERR("bind"));
+
+ pathfd = open(path, O_RDONLY);
+ ATF_REQUIRE_ERRNO(EOPNOTSUPP, pathfd < 0);
+
+ CHECKED_CLOSE(sd);
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, path_access);
ATF_TP_ADD_TC(tp, path_aio);
ATF_TP_ADD_TC(tp, path_capsicum);
+ ATF_TP_ADD_TC(tp, path_coredump);
ATF_TP_ADD_TC(tp, path_directory);
ATF_TP_ADD_TC(tp, path_directory_not_root);
ATF_TP_ADD_TC(tp, path_empty);
@@ -768,11 +866,13 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, path_event);
ATF_TP_ADD_TC(tp, path_fcntl);
ATF_TP_ADD_TC(tp, path_fexecve);
+ ATF_TP_ADD_TC(tp, path_fifo);
ATF_TP_ADD_TC(tp, path_funlinkat);
ATF_TP_ADD_TC(tp, path_io);
ATF_TP_ADD_TC(tp, path_ioctl);
ATF_TP_ADD_TC(tp, path_lock);
ATF_TP_ADD_TC(tp, path_rights);
+ ATF_TP_ADD_TC(tp, path_unix);
return (atf_no_error());
}