commit 3c7049e9063edebbd1934178f263f9f3c9b8ddf5
Author:     Laslo Hunhold <d...@frign.de>
AuthorDate: Mon Sep 23 16:56:28 2019 +0200
Commit:     Laslo Hunhold <d...@frign.de>
CommitDate: Mon Sep 23 16:56:28 2019 +0200

    Use pledge(2) and unveil(2) on OpenBSD
    
    It has been on my todo-list for a long time. I tested it on
    OpenBSD 6.5.
    
    Thanks Richard Ulmer for the reminder.
    
    Signed-off-by: Laslo Hunhold <d...@frign.de>

diff --git a/main.c b/main.c
index d30e85d..c1ff489 100644
--- a/main.c
+++ b/main.c
@@ -325,6 +325,10 @@ main(int argc, char *argv[])
                        die("signal: Failed to set SIG_IGN on SIGCHLD");
                }
 
+               /* limit ourselves to reading the servedir and block further 
unveils */
+               eunveil(servedir, "r");
+               eunveil(NULL, NULL);
+
                /* chroot */
                if (chdir(servedir) < 0) {
                        die("chdir '%s':", servedir);
@@ -343,6 +347,13 @@ main(int argc, char *argv[])
                if (pwd && setuid(pwd->pw_uid) < 0) {
                        die("setuid:");
                }
+
+               if (udsname) {
+                       epledge("stdio rpath proc unix", NULL);
+               } else {
+                       epledge("stdio rpath proc inet", NULL);
+               }
+
                if (getuid() == 0) {
                        die("Won't run as root user", argv0);
                }
@@ -375,6 +386,14 @@ main(int argc, char *argv[])
                }
                exit(0);
        default:
+               /* limit ourselves even further while we are waiting */
+               eunveil(NULL, NULL);
+               if (udsname) {
+                       epledge("stdio cpath", NULL);
+               } else {
+                       epledge("stdio", NULL);
+               }
+
                while ((wpid = wait(&status)) > 0)
                        ;
        }
diff --git a/util.c b/util.c
index 0b05d91..06dcff3 100644
--- a/util.c
+++ b/util.c
@@ -9,6 +9,10 @@
 #include <sys/types.h>
 #include <time.h>
 
+#ifdef __OpenBSD__
+#include <unistd.h>
+#endif /* __OpenBSD__ */
+
 #include "util.h"
 
 char *argv0;
@@ -53,6 +57,32 @@ die(const char *fmt, ...)
        exit(1);
 }
 
+void
+epledge(const char *promises, const char *execpromises)
+{
+       (void)promises;
+       (void)execpromises;
+
+#ifdef __OpenBSD__
+       if (pledge(promises, execpromises) == -1) {
+               die("pledge:");
+       }
+#endif /* __OpenBSD__ */
+}
+
+void
+eunveil(const char *path, const char *permissions)
+{
+       (void)path;
+       (void)permissions;
+
+#ifdef __OpenBSD__
+       if (unveil(path, permissions) == -1) {
+               die("unveil:");
+       }
+#endif /* __OpenBSD__ */
+}
+
 char *
 timestamp(time_t t, char buf[TIMESTAMP_LEN])
 {
diff --git a/util.h b/util.h
index 12b7bd8..7fe65d6 100644
--- a/util.h
+++ b/util.h
@@ -46,6 +46,9 @@ extern char *argv0;
 void warn(const char *, ...);
 void die(const char *, ...);
 
+void epledge(const char *, const char *);
+void eunveil(const char *, const char *);
+
 #define TIMESTAMP_LEN 30
 
 char *timestamp(time_t, char buf[TIMESTAMP_LEN]);

Reply via email to