diff --git a/.gitignore b/.gitignore index 3b5bb47..4dba11e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ __pycache__/ *.gcov devel/a.out *.gcno +devel/test.out.log +devel/test.out.stdout devel/test.out.stderr devel/test_make_safe_uri devel/test_password_equal diff --git a/README.md b/README.md index afd8822..ee8fb2d 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ Features: * Can serve 301 redirects based on Host header. * Uses sendfile() on FreeBSD, Solaris and Linux. * Can use acceptfilter on FreeBSD. +* Can use chroot as non-root on FreeBSD 14+. * At some point worked on FreeBSD, Linux, OpenBSD, Solaris. * ISC license. * suckless.org says [darkhttpd sucks less](http://suckless.org/rocks/). diff --git a/darkhttpd.c b/darkhttpd.c index 4c5719d..4a22ae2 100644 --- a/darkhttpd.c +++ b/darkhttpd.c @@ -71,6 +71,18 @@ static const int debug = 1; #include #include +/* This is for non-root chroot support on FreeBSD 14.0+ */ +/* Must set sysctl security.bsd.unprivileged_chroot=1 to allow this. */ +#ifdef __FreeBSD__ +# if __FreeBSD_version >= 1400000 +# define HAVE_NON_ROOT_CHROOT +# endif +#endif + +#ifdef HAVE_NON_ROOT_CHROOT +#include +#endif + #if defined(__has_feature) # if __has_feature(memory_sanitizer) # include @@ -2882,6 +2894,14 @@ int main(int argc, char **argv) { /* security */ if (want_chroot) { + #ifdef HAVE_NON_ROOT_CHROOT + /* We run this even as root, which should never be a bad thing. */ + int arg = PROC_NO_NEW_PRIVS_ENABLE; + int error = procctl(P_PID, (int)getpid(), PROC_NO_NEW_PRIVS_CTL, &arg); + if (error != 0) + err(1, "procctl"); + #endif + tzset(); /* read /etc/localtime before we chroot */ if (chdir(wwwroot) == -1) err(1, "chdir(%s)", wwwroot);