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_unittest.cc b/dhcp_config_unittest.cc
index 702f67c..434b57c 100644
--- a/dhcp_config_unittest.cc
+++ b/dhcp_config_unittest.cc
@@ -17,6 +17,7 @@
#include "shill/mock_control.h"
#include "shill/mock_dhcp_proxy.h"
#include "shill/mock_glib.h"
+#include "shill/mock_minijail.h"
#include "shill/property_store_unittest.h"
#include "shill/proxy_factory.h"
@@ -43,6 +44,7 @@
DHCPConfigTest()
: proxy_(new MockDHCPProxy()),
proxy_factory_(this),
+ minijail_(new MockMinijail()),
config_(new DHCPConfig(&control_,
dispatcher(),
DHCPProvider::GetInstance(),
@@ -54,12 +56,17 @@
virtual void SetUp() {
config_->proxy_factory_ = &proxy_factory_;
+ config_->minijail_ = minijail_.get();
}
virtual void TearDown() {
config_->proxy_factory_ = NULL;
+ config_->minijail_ = NULL;
}
+ DHCPConfigRefPtr CreateMockMinijailConfig(const string &hostname,
+ const string &lease_suffix,
+ bool arp_gateway);
DHCPConfigRefPtr CreateRunningConfig(const string &hostname,
const string &lease_suffix,
bool arp_gateway);
@@ -88,12 +95,31 @@
scoped_ptr<MockDHCPProxy> proxy_;
TestProxyFactory proxy_factory_;
MockControl control_;
+ scoped_ptr<MockMinijail> minijail_;
DHCPConfigRefPtr config_;
};
const int DHCPConfigTest::kPID = 123456;
const unsigned int DHCPConfigTest::kTag = 77;
+DHCPConfigRefPtr DHCPConfigTest::CreateMockMinijailConfig(
+ const string &hostname,
+ const string &lease_suffix,
+ bool arp_gateway) {
+ DHCPConfigRefPtr config(new DHCPConfig(&control_,
+ dispatcher(),
+ DHCPProvider::GetInstance(),
+ kDeviceName,
+ hostname,
+ lease_suffix,
+ arp_gateway,
+ glib()));
+ config->minijail_ = minijail_.get();
+ EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
+
+ return config;
+}
+
DHCPConfigRefPtr DHCPConfigTest::CreateRunningConfig(const string &hostname,
const string &lease_suffix,
bool arp_gateway) {
@@ -105,8 +131,9 @@
lease_suffix,
arp_gateway,
glib()));
- EXPECT_CALL(*glib(), SpawnAsync(_, _, _, _, _, _, _, _))
- .WillOnce(DoAll(SetArgumentPointee<6>(kPID), Return(true)));
+ config->minijail_ = minijail_.get();
+ EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _))
+ .WillOnce(DoAll(SetArgumentPointee<2>(kPID), Return(true)));
EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
EXPECT_TRUE(config->Start());
EXPECT_EQ(kPID, config->pid_);
@@ -132,7 +159,6 @@
void DHCPConfigTest::StopRunningConfigAndExpect(DHCPConfigRefPtr config,
bool lease_file_exists) {
- EXPECT_CALL(*glib(), SpawnClosePID(kPID)).Times(1);
DHCPConfig::ChildWatchCallback(kPID, 0, config.get());
EXPECT_EQ(NULL, DHCPProvider::GetInstance()->GetConfig(kPID).get());
@@ -210,8 +236,7 @@
}
TEST_F(DHCPConfigTest, StartFail) {
- EXPECT_CALL(*glib(), SpawnAsync(_, _, _, _, _, _, _, _))
- .WillOnce(Return(false));
+ EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
EXPECT_CALL(*glib(), ChildWatchAdd(_, _, _)).Times(0);
EXPECT_FALSE(config_->Start());
EXPECT_EQ(0, config_->pid_);
@@ -244,57 +269,28 @@
}
TEST_F(DHCPConfigTest, StartWithHostname) {
- EXPECT_CALL(*glib(),
- SpawnAsync(_, IsDHCPCDArgs(true, true, true), _, _, _, _, _, _))
- .WillOnce(Return(false));
+ EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
EXPECT_FALSE(config_->Start());
}
TEST_F(DHCPConfigTest, StartWithoutHostname) {
- DHCPConfigRefPtr config(new DHCPConfig(&control_,
- dispatcher(),
- DHCPProvider::GetInstance(),
- kDeviceName,
- "",
- kLeaseFileSuffix,
- kArpGateway,
- glib()));
-
- EXPECT_CALL(*glib(),
- SpawnAsync(_, IsDHCPCDArgs(false, true, true), _, _, _, _, _, _))
- .WillOnce(Return(false));
+ DHCPConfigRefPtr config = CreateMockMinijailConfig("",
+ kLeaseFileSuffix,
+ kArpGateway);
EXPECT_FALSE(config->Start());
}
TEST_F(DHCPConfigTest, StartWithoutArpGateway) {
- DHCPConfigRefPtr config(new DHCPConfig(&control_,
- dispatcher(),
- DHCPProvider::GetInstance(),
- kDeviceName,
- kHostName,
- kLeaseFileSuffix,
- false,
- glib()));
-
- EXPECT_CALL(*glib(),
- SpawnAsync(_, IsDHCPCDArgs(true, false, true), _, _, _, _, _, _))
- .WillOnce(Return(false));
+ DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
+ kLeaseFileSuffix,
+ false);
EXPECT_FALSE(config->Start());
}
TEST_F(DHCPConfigTest, StartWithoutLeaseSuffix) {
- DHCPConfigRefPtr config(new DHCPConfig(&control_,
- dispatcher(),
- DHCPProvider::GetInstance(),
- kDeviceName,
- kHostName,
- kDeviceName,
- kArpGateway,
- glib()));
-
- EXPECT_CALL(*glib(),
- SpawnAsync(_, IsDHCPCDArgs(true, true, false), _, _, _, _, _, _))
- .WillOnce(Return(false));
+ DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
+ kDeviceName,
+ kArpGateway);
EXPECT_FALSE(config->Start());
}
@@ -433,9 +429,8 @@
config_->child_watch_tag_ = kTag1;
DHCPProvider::GetInstance()->BindPID(kPID1, config_);
EXPECT_CALL(*glib(), SourceRemove(kTag1)).WillOnce(Return(true));
- EXPECT_CALL(*glib(), SpawnClosePID(kPID1)).Times(1);
- EXPECT_CALL(*glib(), SpawnAsync(_, _, _, _, _, _, _, _))
- .WillOnce(DoAll(SetArgumentPointee<6>(kPID2), Return(true)));
+ EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
+ DoAll(SetArgumentPointee<2>(kPID2), Return(true)));
EXPECT_CALL(*glib(), ChildWatchAdd(kPID2, _, _)).WillOnce(Return(kTag2));
EXPECT_TRUE(config_->Restart());
EXPECT_EQ(kPID2, config_->pid_);
@@ -450,9 +445,8 @@
const int kPID = 777;
const unsigned int kTag = 66;
EXPECT_CALL(*glib(), SourceRemove(_)).Times(0);
- EXPECT_CALL(*glib(), SpawnClosePID(_)).Times(0);
- EXPECT_CALL(*glib(), SpawnAsync(_, _, _, _, _, _, _, _))
- .WillOnce(DoAll(SetArgumentPointee<6>(kPID), Return(true)));
+ EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
+ DoAll(SetArgumentPointee<2>(kPID), Return(true)));
EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
EXPECT_TRUE(config_->Restart());
EXPECT_EQ(kPID, config_->pid_);
@@ -481,9 +475,7 @@
Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
config_->lease_acquisition_timeout_seconds_ = 0;
config_->proxy_.reset(proxy_.release());
- EXPECT_CALL(*glib(),
- SpawnAsync(_, IsDHCPCDArgs(true, true, true), _, _, _, _, _, _))
- .WillOnce(Return(true));
+ EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
config_->Start();
config_->dispatcher_->DispatchPendingEvents();
EXPECT_TRUE(callback_test.called());
@@ -492,10 +484,8 @@
TEST_F(DHCPConfigTest, Stop) {
// Ensure no crashes.
const int kPID = 1 << 17; // Ensure unknown positive PID.
- config_->Stop();
config_->pid_ = kPID;
config_->Stop();
- EXPECT_CALL(*glib(), SpawnClosePID(kPID)).Times(1); // Invoked by destructor.
EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
}