Stop security-manager before unmounting /opt/usr 67/168867/5
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 31 Jan 2018 16:01:47 +0000 (17:01 +0100)
committerDariusz Michaluk <d.michaluk@samsung.com>
Wed, 7 Feb 2018 08:58:33 +0000 (08:58 +0000)
Security-manager creates mounts in a mount namespace that are invisible to
oded. Although /opt/usr is unmounted in oded's namespace it is still mounted
in the one used by SM. As a result device mapper can't use the device to
load the table.

This commit adds security-manager.service and socket to the list of known units
that have to be killed before unmounting /opt/usr. Socket is stopped to prevent
security-manager from being restarted. This is just a temporary solution. It
does not prevent other services from blocking ode by using mount namespaces.

Change-Id: I53584f17efc56fa39a503025d4f68010c3b3dbb3

server/internal-encryption.cpp

index 4ff4539..7c9051e 100644 (file)
@@ -60,9 +60,9 @@ const std::vector<std::string> wipeCommand = {
     "com.samsung.factoryreset.start.setting"
 };
 
-void stopKnownSystemdServices()
+void stopKnownSystemdUnits()
 {
-       std::vector<std::string> knownSystemdServices;
+       std::vector<std::string> knownSystemdUnits;
        dbus::Connection& systemDBus = dbus::Connection::getSystem();
        dbus::VariantIterator iter;
 
@@ -87,51 +87,54 @@ void stopKnownSystemdServices()
                        break;
                }
 
-               std::string service(dataStr[0]);
-               if (service.compare(0, 5, "user@") == 0 ||
-                       service == "tlm.service" ||
-                       service == "resourced.service") {
-                       knownSystemdServices.push_back(service);
+               std::string unit(dataStr[0]);
+               if (unit == "security-manager.socket") {
+                       knownSystemdUnits.insert(knownSystemdUnits.begin(), unit);
+               } else if (unit.compare(0, 5, "user@") == 0 ||
+                       unit == "tlm.service" ||
+                       unit == "resourced.service" ||
+                       unit == "security-manager.service") {
+                       knownSystemdUnits.push_back(unit);
                }
        }
 
-       for (const std::string& service : knownSystemdServices) {
-               INFO(SINK, "Stopping service: " + service);
+       for (const std::string& unit : knownSystemdUnits) {
+               INFO(SINK, "Stopping unit: " + unit);
                systemDBus.methodcall("org.freedesktop.systemd1",
                                                                "/org/freedesktop/systemd1",
                                                                "org.freedesktop.systemd1.Manager",
                                                                "StopUnit",
-                                                               -1, "", "(ss)", service.c_str(), "flush");
+                                                               -1, "", "(ss)", unit.c_str(), "flush");
        }
 
-       sleep(1);
+       sleep(1); // TODO wait for confirmation from systemd instead
 }
 
-void stopDependedSystemdServices()
+void stopDependedSystemdUnits()
 {
        dbus::Connection& systemDBus = dbus::Connection::getSystem();
-       std::set<std::string> servicesToStop;
+       std::set<std::string> unitsToStop;
 
        for (pid_t pid : runtime::FileUser::getList(INTERNAL_PATH, true)) {
                try {
-                       char *service;
+                       char *unit;
                        systemDBus.methodcall("org.freedesktop.systemd1",
                                                                        "/org/freedesktop/systemd1",
                                                                        "org.freedesktop.systemd1.Manager",
                                                                        "GetUnitByPID",
                                                                        -1, "(o)", "(u)", (unsigned int)pid)
-                                                                               .get("(o)", &service);
-                       servicesToStop.insert(service);
+                                                                               .get("(o)", &unit);
+                       unitsToStop.insert(unit);
                } catch (runtime::Exception &e) {
                        INFO(SINK, "Killing process: " + std::to_string(pid));
                        ::kill(pid, SIGKILL);
                }
        }
 
-       for (const std::string& service : servicesToStop) {
-               INFO(SINK, "Stopping service: " + service);
+       for (const std::string& unit : unitsToStop) {
+               INFO(SINK, "Stopping unit: " + unit);
                systemDBus.methodcall("org.freedesktop.systemd1",
-                                                               service,
+                                                               unit,
                                                                "org.freedesktop.systemd1.Unit",
                                                                "Stop",
                                                                -1, "", "(s)", "flush");
@@ -212,7 +215,7 @@ void unmountInternalStorage(const std::string& source)
                        }
                }
                if (!unmounted)
-                       stopDependedSystemdServices();
+                       stopDependedSystemdUnits();
        }
 }
 
@@ -309,7 +312,7 @@ int InternalEncryptionServer::umount()
 
        INFO(SINK, "Closing all processes using internal storage.");
        try {
-               stopDependedSystemdServices();
+               stopDependedSystemdUnits();
                INFO(SINK, "Umounting internal storage.");
                engine->umount();
        } catch (runtime::Exception &e) {
@@ -334,14 +337,15 @@ int InternalEncryptionServer::encrypt(const std::string& password, unsigned int
 
        auto encryptWorker = [masterKey, options, this]() {
                try {
+                       INFO(SINK, "Closing all known systemd services that might be using internal storage.");
+                       stopKnownSystemdUnits();
+
                        std::string source = engine->getSource();
                        auto mntPaths = findMountPointsByDevice(source);
 
                        if (!mntPaths.empty()) {
-                               INFO(SINK, "Closing all known systemd services that might be using internal storage.");
-                               stopKnownSystemdServices();
                                INFO(SINK, "Closing all processes using internal storage.");
-                               stopDependedSystemdServices();
+                               stopDependedSystemdUnits();
 
                                INFO(SINK, "Unmounting internal storage.");
                                unmountInternalStorage(source);
@@ -388,9 +392,9 @@ int InternalEncryptionServer::decrypt(const std::string& password)
                try {
                        if (engine->isMounted()) {
                                INFO(SINK, "Closing all known systemd services that might be using internal storage.");
-                               stopKnownSystemdServices();
+                               stopKnownSystemdUnits();
                                INFO(SINK, "Closing all processes using internal storage.");
-                               stopDependedSystemdServices();
+                               stopDependedSystemdUnits();
 
                                INFO(SINK, "Umounting internal storage.");
                                while (1) {
@@ -398,7 +402,7 @@ int InternalEncryptionServer::decrypt(const std::string& password)
                                                engine->umount();
                                                break;
                                        } catch (runtime::Exception& e) {
-                                               stopDependedSystemdServices();
+                                               stopDependedSystemdUnits();
                                        }
                                }
                        }