commit 3c7049e9063edebbd1934178f263f9f3c9b8ddf5
parent 32223c96bdee8f94980d3a1877a643a4d59f897f
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:
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 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
@@ -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]);