summaryrefslogtreecommitdiffstats
path: root/src/privsep.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-06-09 18:25:18 +0100
committerRoy Marples <roy@marples.name>2020-06-09 18:25:18 +0100
commitbc4a5e852a8b810bdbe5679ef3e03a634709d722 (patch)
tree77ab40db824324751c6617c325ea57a8fcdcc3f1 /src/privsep.c
parent7e4b8c2ec9b521495a5c4906f8315f0530dd0ffd (diff)
downloaddhcpcd-bc4a5e852a8b810bdbe5679ef3e03a634709d722.tar.xz
privsep: Implement a resource limited sandbox
For systems without Capsicum or Pledge we can create a resource limited sandbox provided that either ppoll(2) or works with RLIMIT_NOFILES set to zero. As far as dhcpcd is concerned, that means Linux and Solaris won't work with this, but NetBSD and DragonFlyBSD will. To achieve this, a special control proxy process will be spawned just to accept new connections over the control socket because this *cannot* be limited by RLIMIT_NOFILES.
Diffstat (limited to 'src/privsep.c')
-rw-r--r--src/privsep.c52
1 files changed, 22 insertions, 30 deletions
diff --git a/src/privsep.c b/src/privsep.c
index 3b836893..a4b03fde 100644
--- a/src/privsep.c
+++ b/src/privsep.c
@@ -39,7 +39,6 @@
* this in a script or something.
*/
-#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -129,36 +128,11 @@ ps_dropprivs(struct dhcpcd_ctx *ctx)
return -1;
}
-#if defined(HAVE_CAPSICUM) || defined(HAVE_PLEDGE)
- /* Resource limits are not needed for these sandboxes */
-#else
- struct rlimit rzero = { .rlim_cur = 0, .rlim_max = 0 };
-
- /* We can't use RLIMIT_NOFILE because that breaks our control socket.
- * XXX Offload to a new process? */
-#if 0
-#ifndef __linux__ /* breaks ppoll */
- /* Prohibit new files, sockets, etc */
- if (setrlimit(RLIMIT_NOFILE, &rzero) == -1) {
- logerr("setrlimit RLIMIT_NOFILE");
- return -1;
- }
-#endif
-#endif
-
- /* Prohibit large files */
- if (setrlimit(RLIMIT_FSIZE, &rzero) == -1) {
- logerr("setrlimit RLIMIT_FSIZE");
+#ifdef PRIVSEP_CONTROLLER
+ if (ps_ctl_limitresources(ctx) == -1)
return -1;
- }
-
-#ifdef RLIMIT_NPROC
- /* Prohibit forks */
- if (setrlimit(RLIMIT_NPROC, &rzero) == -1) {
- logerr("setrlimit RLIMIT_NPROC");
- return -1;
- }
-#endif
+#elif !defined(HAVE_CAPSIUM) && !defined(HAVE_PLEDGE)
+#warning No sandbox support
#endif
return 0;
@@ -437,6 +411,18 @@ ps_start(struct dhcpcd_ctx *ctx)
}
started:
+#ifdef PRIVSEP_CONTROLLER
+ if (!(ctx->options & DHCPCD_TEST)) {
+ switch (pid = ps_ctl_start(ctx)) {
+ case -1:
+ return -1;
+ case 0:
+ return 0;
+ default:
+ logdebugx("spawned controller on PID %d", pid);
+ }
+ }
+#endif
#ifdef ARC4RANDOM_H
/* Seed the random number generator early incase it needs /dev/urandom
@@ -491,6 +477,12 @@ ps_stop(struct dhcpcd_ctx *ctx)
ctx->eloop == NULL)
return 0;
+#ifdef PRIVSEP_CONTROLLER
+ r = ps_ctl_stop(ctx);
+ if (r != 0)
+ ret = r;
+#endif
+
r = ps_inet_stop(ctx);
if (r != 0)
ret = r;