From 0bee16bd74c33631f745dc53e0c04300d8fb6e11 Mon Sep 17 00:00:00 2001 From: benno Date: Thu, 1 Sep 2022 14:23:25 +0000 Subject: [PATCH] add checks that unveil() is doing the right thing irt. bind() and connect() --- regress/sys/kern/unveil/syscalls.c | 98 +++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/regress/sys/kern/unveil/syscalls.c b/regress/sys/kern/unveil/syscalls.c index b09b72c377b..2546b9942b6 100644 --- a/regress/sys/kern/unveil/syscalls.c +++ b/regress/sys/kern/unveil/syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syscalls.c,v 1.32 2022/01/09 10:36:52 claudio Exp $ */ +/* $OpenBSD: syscalls.c,v 1.33 2022/09/01 14:23:25 benno Exp $ */ /* * Copyright (c) 2017-2019 Bob Beck @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,8 @@ #include #include #include +#include +#include pid_t child; char uv_dir1[] = "/tmp/uvdir1.XXXXXX"; /* unveiled */ @@ -1006,6 +1009,98 @@ test_noaccess_node(int do_uv) return 0; } +static int +test_bind_unix_socket(int do_uv) +{ + struct sockaddr_un sun1, sun2, sun3; + + int fd1, c_fd1, fd2, c_fd2, fd3; + char *path1, *path2, *path3; + + char uv_dir3[] = "/tmp/uvdir3.XXXXXX"; + + if (asprintf(&path1, "%s/1.sock", uv_dir1) == -1) + err(1, NULL); + if (asprintf(&path2, "%s/2.sock", uv_dir2) == -1) + err(1, NULL); + if (asprintf(&path3, "%s/3.sock", uv_dir3) == -1) + err(1, NULL); + + memset(&sun1, 0, sizeof(sun1)); + sun1.sun_family = AF_UNIX; + strlcpy(sun1.sun_path, path1, sizeof(sun1.sun_path)); + + memset(&sun2, 0, sizeof(sun2)); + sun2.sun_family = AF_UNIX; + strlcpy(sun2.sun_path, path2, sizeof(sun2.sun_path)); + + memset(&sun3, 0, sizeof(sun3)); + sun3.sun_family = AF_UNIX; + strlcpy(sun3.sun_path, path3, sizeof(sun3.sun_path)); + + if (unlink(path1) == -1) + if (errno != ENOENT) { + warn("%s: unlink %s", __func__, path1); + return (-1); + } + if (unlink(path2) == -1) + if (errno != ENOENT) { + warn("%s: unlink %s", __func__, path2); + return (-1); + } + if (unlink(path3) == -1) + if (errno != ENOENT) { + warn("%s: unlink %s", __func__, path3); + return (-1); + } + + if (do_uv) { + printf("testing bind and connect on unix socket\n"); + /* printf("testing bind on unix socket %s and %s\n", path1, path2); */ + if (unveil(uv_dir1, "wc") == -1) /* both bind and connect work */ + err(1, "unveil"); + if (unveil(uv_dir2, "c") == -1) /* bind works, connect fails */ + err(1, "unveil"); + if (unveil(uv_dir3, "") == -1) /* no bind, dont test anything else */ + err(1, "unveil"); + } + + if ((fd1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + err(1, "%s: socket", __func__); + UV_SHOULD_SUCCEED((bind(fd1, (struct sockaddr *)&sun1, sizeof(sun1)) == -1), "bind"); + if (listen(fd1, 5) == -1) + err(1, "%s: listen", __func__); + + if ((fd2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + err(1, "%s: socket", __func__); + UV_SHOULD_SUCCEED((bind(fd2, (struct sockaddr *)&sun2, sizeof(sun2)) == -1), "bind"); + if (listen(fd2, 5) == -1) + err(1, "%s: listen", __func__); + + if ((fd3 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + err(1, "%s: socket", __func__); + UV_SHOULD_ENOENT((bind(fd3, (struct sockaddr *)&sun3, sizeof(sun3)) == -1), "bind"); + + /* Connect to control socket. */ + + if ((c_fd1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + err(1, "socket"); + UV_SHOULD_SUCCEED((connect(c_fd1, (struct sockaddr *)&sun1, sizeof(sun1)) == -1), "connect"); + + if ((c_fd2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + err(1, "socket"); + UV_SHOULD_EACCES((connect(c_fd2, (struct sockaddr *)&sun2, sizeof(sun2)) == -1), "connect"); + + close(fd1); + close(c_fd1); + close(fd2); + close(c_fd2); + return 0; +} + + + + int main (int argc, char *argv[]) { @@ -1058,5 +1153,6 @@ main (int argc, char *argv[]) failures += runcompare(test_fork_locked); failures += runcompare(test_intermediate_node); failures += runcompare(test_noaccess_node); + failures += runcompare(test_bind_unix_socket); exit(failures); } -- 2.20.1