Launch dhcpcd using Minijail.
dhcpcd runs as root and listens on the network. Launch it using Minijail
so that we can run it as a regular user, mitigating the risk of an eventual
compromise.
Add a mock Minijail wrapper for unittesting.
BUG=chromium-os:28336
TEST=dhcp_config_unittest
TEST=network_netperf2
TEST=Manual connection to ethernet, GoogleGuest, Google-A.
CQ-DEPEND=I243e02c82f70c6a3469ca712e539ec9fb6e3e4d4
Change-Id: I14c4e843eba478ed39b10fa4fcb0e25eb3186c1a
Reviewed-on: https://gerrit.chromium.org/gerrit/20414
Commit-Ready: Jorge Lucangeli Obes <jorgelo@chromium.org>
Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Tested-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
diff --git a/dhcp_config.cc b/dhcp_config.cc
index e1f610d..ab58d1a 100644
--- a/dhcp_config.cc
+++ b/dhcp_config.cc
@@ -17,6 +17,7 @@
#include "shill/event_dispatcher.h"
#include "shill/glib.h"
#include "shill/ip_address.h"
+#include "shill/minijail.h"
#include "shill/proxy_factory.h"
#include "shill/scope_logger.h"
@@ -42,6 +43,7 @@
const char DHCPConfig::kDHCPCDPathFormatPID[] =
"var/run/dhcpcd/dhcpcd-%s.pid";
const int DHCPConfig::kDHCPTimeoutSeconds = 30;
+const char DHCPConfig::kDHCPCDUser[] = "dhcp";
const int DHCPConfig::kMinMTU = 576;
const char DHCPConfig::kReasonBound[] = "BOUND";
const char DHCPConfig::kReasonFail[] = "FAIL";
@@ -72,7 +74,8 @@
root_("/"),
weak_ptr_factory_(this),
dispatcher_(dispatcher),
- glib_(glib) {
+ glib_(glib),
+ minijail_(Minijail::GetInstance()) {
SLOG(DHCP, 2) << __func__ << ": " << device_name;
if (lease_file_suffix_.empty()) {
lease_file_suffix_ = device_name;
@@ -175,18 +178,18 @@
}
args.push_back(const_cast<char *>(interface_arg.c_str()));
args.push_back(NULL);
- char *envp[1] = { NULL };
+
+ struct minijail *jail = minijail_->New();
+ minijail_->DropRoot(jail, kDHCPCDUser);
+ minijail_->UseCapabilities(jail,
+ CAP_TO_MASK(CAP_NET_BIND_SERVICE) |
+ CAP_TO_MASK(CAP_NET_BROADCAST) |
+ CAP_TO_MASK(CAP_NET_ADMIN) |
+ CAP_TO_MASK(CAP_NET_RAW));
CHECK(!pid_);
- if (!glib_->SpawnAsync(NULL,
- args.data(),
- envp,
- G_SPAWN_DO_NOT_REAP_CHILD,
- NULL,
- NULL,
- &pid_,
- NULL)) {
- LOG(ERROR) << "Unable to spawn " << kDHCPCDPath;
+ if (!minijail_->RunAndDestroy(jail, args, &pid_)) {
+ LOG(ERROR) << "Unable to spawn " << kDHCPCDPath << " in a jail.";
return false;
}
LOG(INFO) << "Spawned " << kDHCPCDPath << " with pid: " << pid_;
@@ -320,10 +323,7 @@
glib_->SourceRemove(child_watch_tag_);
child_watch_tag_ = 0;
}
- if (pid_) {
- glib_->SpawnClosePID(pid_);
- pid_ = 0;
- }
+ pid_ = 0;
proxy_.reset();
if (lease_file_suffix_ == device_name()) {
// If the lease file suffix was left as default, clean it up at exit.