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>
This commit is contained in:
Laslo Hunhold 2019-09-23 16:56:28 +02:00
parent 32223c96bd
commit 3c7049e906
No known key found for this signature in database
GPG key ID: 69576BD24CFCB980
3 changed files with 52 additions and 0 deletions

19
main.c
View file

@ -325,6 +325,10 @@ main(int argc, char *argv[])
die("signal: Failed to set SIG_IGN on SIGCHLD"); 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 */ /* chroot */
if (chdir(servedir) < 0) { if (chdir(servedir) < 0) {
die("chdir '%s':", servedir); die("chdir '%s':", servedir);
@ -343,6 +347,13 @@ main(int argc, char *argv[])
if (pwd && setuid(pwd->pw_uid) < 0) { if (pwd && setuid(pwd->pw_uid) < 0) {
die("setuid:"); die("setuid:");
} }
if (udsname) {
epledge("stdio rpath proc unix", NULL);
} else {
epledge("stdio rpath proc inet", NULL);
}
if (getuid() == 0) { if (getuid() == 0) {
die("Won't run as root user", argv0); die("Won't run as root user", argv0);
} }
@ -375,6 +386,14 @@ main(int argc, char *argv[])
} }
exit(0); exit(0);
default: 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) while ((wpid = wait(&status)) > 0)
; ;
} }

30
util.c
View file

@ -9,6 +9,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <time.h> #include <time.h>
#ifdef __OpenBSD__
#include <unistd.h>
#endif /* __OpenBSD__ */
#include "util.h" #include "util.h"
char *argv0; char *argv0;
@ -53,6 +57,32 @@ die(const char *fmt, ...)
exit(1); 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 * char *
timestamp(time_t t, char buf[TIMESTAMP_LEN]) timestamp(time_t t, char buf[TIMESTAMP_LEN])
{ {

3
util.h
View file

@ -46,6 +46,9 @@ extern char *argv0;
void warn(const char *, ...); void warn(const char *, ...);
void die(const char *, ...); void die(const char *, ...);
void epledge(const char *, const char *);
void eunveil(const char *, const char *);
#define TIMESTAMP_LEN 30 #define TIMESTAMP_LEN 30
char *timestamp(time_t, char buf[TIMESTAMP_LEN]); char *timestamp(time_t, char buf[TIMESTAMP_LEN]);