Fix mount state check in internal encryption 22/160722/23
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 27 Nov 2017 13:22:25 +0000 (14:22 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Tue, 28 Nov 2017 15:34:57 +0000 (16:34 +0100)
Oded is keeping the mount state of internal memory in a variable. If oded is
restarted, the internal memory is mounted by ode-recovery (during FOTA) or
manaully via the command line oded may end up with invalid mount state. This
commit makes ode check the actual state of the dm mapping instead.

Change-Id: I2c564e8db858880840ea3dae6d9ebc1fb4f0a7c9

server/engine/encryption/dmcrypt-engine.cpp
server/engine/encryption/dmcrypt-engine.h

index 4d57c54..306d1bb 100644 (file)
@@ -21,7 +21,6 @@
 #include <fcntl.h>
 #include <errno.h>
 
-
 #include <klay/error.h>
 #include <klay/exception.h>
 #include <klay/filesystem.h>
@@ -30,6 +29,7 @@
 #include "../../ext4-tool.h"
 
 #include "dmcrypt-engine.h"
+#include "misc.h"
 
 #define DM_MAX_BUFFER_SIZE             4096
 #define DM_KEY_MIN_LEN_BYTE            32
@@ -197,6 +197,36 @@ void destroyCryptoBlkDev(const std::string &cryptoBlkDev)
        }
 }
 
+std::string getCryptoBlkDevName(const std::string &mountName)
+{
+       char dmBuf[DM_MAX_BUFFER_SIZE];
+       int fd;
+
+       // Open dm control IOCTL
+       if ((fd = open("/dev/mapper/control", O_RDWR)) < 0) {
+               throw runtime::Exception("Cannot open device-mapper");
+       }
+
+       auto dmIo = (struct dm_ioctl *)dmBuf;
+
+       // Get the device status, in particular, the mount_name of it's device file
+       initDMIoctl(dmBuf, DM_MAX_BUFFER_SIZE, mountName, 0);
+       int ret = ioctl(fd, DM_DEV_STATUS, dmBuf);
+       close(fd);
+
+       // No such device
+       if (ret)
+               return std::string();
+
+       // Not opened
+       if (dmIo->open_count == 0)
+               return std::string();
+
+       // Get the device name
+       unsigned int dmMinor = (dmIo->dev & 0xff) | ((dmIo->dev >> 12) & 0xfff00);
+       return std::string("/dev/dm-") + std::to_string(dmMinor);
+}
+
 BinaryData sanitizeKey(const BinaryData &key)
 {
        if (key.size() < DM_KEY_MIN_LEN_BYTE)
@@ -237,7 +267,7 @@ void copyInPlace(const std::string &source, const std::string &destination,
 } // namepsace
 
 DMCryptEngine::DMCryptEngine(const std::string &src, const std::string &dest, const ProgressBar &prgsBar) :
-       source(src), destination(dest), progress(prgsBar), mounted(false)
+       source(src), destination(dest), progress(prgsBar)
 {
 }
 
@@ -252,8 +282,6 @@ void DMCryptEngine::mount(const BinaryData &key, unsigned int options)
 
        if (::mount(cryptoBlkDev.c_str(), destination.c_str(), "ext4", 0, 0) < 0)
                throw runtime::Exception(runtime::GetSystemErrorMessage());
-
-       mounted = true;
 }
 
 void DMCryptEngine::umount()
@@ -262,13 +290,23 @@ void DMCryptEngine::umount()
                throw runtime::Exception(runtime::GetSystemErrorMessage());
 
        destroyCryptoBlkDev(DM_DEFAULT_LABEL_NAME);
-
-       mounted = false;
 }
 
 bool DMCryptEngine::isMounted()
 {
-       return mounted;
+       // TODO isMounted() vs. isOpened()
+       std::string cryptoDev = getCryptoBlkDevName(DM_DEFAULT_LABEL_NAME);
+       if (cryptoDev.empty())
+               return false;
+
+       Mtab mtab;
+       struct ::mntent* entry;
+       while ((entry = mtab.next()) != NULL) {
+               if (cryptoDev == entry->mnt_fsname && destination == entry->mnt_dir)
+                       return true;
+       }
+
+       return false;
 }
 
 void DMCryptEngine::encrypt(const BinaryData &key, unsigned int options)
index 0320267..1761598 100644 (file)
@@ -18,7 +18,6 @@
 #define __DMCRYPT_ENGINE_H__
 
 #include <string>
-#include <atomic>
 
 #include "progress-bar.h"
 #include "rmi/common.h"
@@ -57,7 +56,6 @@ public:
 private:
        std::string source, destination;
        ProgressBar progress;
-       std::atomic<bool> mounted;
 };
 
 } // namespace ode