add checks that unveil() is doing the right thing irt. bind() and connect()
authorbenno <benno@openbsd.org>
Thu, 1 Sep 2022 14:23:25 +0000 (14:23 +0000)
committerbenno <benno@openbsd.org>
Thu, 1 Sep 2022 14:23:25 +0000 (14:23 +0000)
regress/sys/kern/unveil/syscalls.c

index b09b72c..2546b99 100644 (file)
@@ -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 <beck@openbsd.org>
@@ -18,6 +18,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include <unistd.h>
 #include <dirent.h>
 #include <err.h>
@@ -27,6 +28,8 @@
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/mount.h>
+#include <sys/socket.h>
+#include <sys/un.h>
 
 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);
 }