Use pledge(2) and unveil(2) on OpenBSD - quark - quark web server | |
git clone git://git.suckless.org/quark | |
Log | |
Files | |
Refs | |
LICENSE | |
--- | |
commit 3c7049e9063edebbd1934178f263f9f3c9b8ddf5 | |
parent 32223c96bdee8f94980d3a1877a643a4d59f897f | |
Author: Laslo Hunhold <[email protected]> | |
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 <[email protected]> | |
Diffstat: | |
M main.c | 19 +++++++++++++++++++ | |
M util.c | 30 ++++++++++++++++++++++++++++++ | |
M util.h | 3 +++ | |
3 files changed, 52 insertions(+), 0 deletions(-) | |
--- | |
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 u… | |
+ 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 | |
@@ -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 | |
@@ -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]); |