Use pledge(2) and unveil(2) on OpenBSD - quark - quark web server
 (HTM) git clone git://git.suckless.org/quark
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit 3c7049e9063edebbd1934178f263f9f3c9b8ddf5
 (DIR) parent 32223c96bdee8f94980d3a1877a643a4d59f897f
 (HTM) Author: Laslo Hunhold <dev@frign.de>
       Date:   Mon, 23 Sep 2019 16:56:28 +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 <dev@frign.de>
       
       Diffstat:
         M main.c                              |      19 +++++++++++++++++++
         M util.c                              |      30 ++++++++++++++++++++++++++++++
         M util.h                              |       3 +++
       
       3 files changed, 52 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git 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)
                                ;
                }
 (DIR) diff --git 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])
        {
 (DIR) diff --git 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]);