Test for races in IptablesRestoreController::Init.
Bug: 28362720
Test: angler builds, boots
Test: netd_{unit,integration}_test pass
Change-Id: I73ed28c7e7edaeb65a3b346b89ec69f472fd5974
diff --git a/server/IptablesRestoreControllerTest.cpp b/server/IptablesRestoreControllerTest.cpp
index 43041ec..29e1e01 100644
--- a/server/IptablesRestoreControllerTest.cpp
+++ b/server/IptablesRestoreControllerTest.cpp
@@ -20,12 +20,14 @@
#include <sys/socket.h>
#include <sys/un.h>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#define LOG_TAG "IptablesRestoreControllerTest"
#include <cutils/log.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <netdutils/MockSyscalls.h>
#include "IptablesRestoreController.h"
#include "NetdConstants.h"
@@ -37,6 +39,9 @@
using android::base::Join;
using android::base::StringPrintf;
+using android::netdutils::ScopedMockSyscalls;
+using testing::Return;
+using testing::StrictMock;
class IptablesRestoreControllerTest : public ::testing::Test {
public:
@@ -60,6 +65,10 @@
deleteTestChain();
}
+ void Init() {
+ con.Init();
+ }
+
pid_t getIpRestorePid(const IptablesRestoreController::IptablesProcessType type) {
return con.getIpRestorePid(type);
};
@@ -270,3 +279,28 @@
iterations, timeTaken, timeTaken / 2 / iterations);
}
}
+
+TEST_F(IptablesRestoreControllerTest, TestStartup) {
+ // Tests that IptablesRestoreController::Init never sets its processes to null pointers if
+ // fork() succeeds.
+ {
+ // Mock fork(), and check that initializing 100 times never results in a null pointer.
+ constexpr int NUM_ITERATIONS = 100; // Takes 100-150ms on angler.
+ constexpr pid_t FAKE_PID = 2000000001;
+ StrictMock<ScopedMockSyscalls> sys;
+
+ EXPECT_CALL(sys, fork()).Times(NUM_ITERATIONS * 2).WillRepeatedly(Return(FAKE_PID));
+ for (int i = 0; i < NUM_ITERATIONS; i++) {
+ Init();
+ EXPECT_NE(0, getIpRestorePid(IptablesRestoreController::IPTABLES_PROCESS));
+ EXPECT_NE(0, getIpRestorePid(IptablesRestoreController::IP6TABLES_PROCESS));
+ }
+ }
+
+ // The controller is now in an invalid state: the pipes are connected to working iptables
+ // processes, but the PIDs are set to FAKE_PID. Send a malformed command to ensure that the
+ // processes terminate and close the pipes, then send a valid command to have the controller
+ // re-initialize properly now that fork() is no longer mocked.
+ EXPECT_EQ(-1, con.execute(V4V6, "malformed command\n", nullptr));
+ EXPECT_EQ(0, con.execute(V4V6, "#Test\n", nullptr));
+}