From: seolheui,kim Date: Fri, 10 Feb 2017 08:26:35 +0000 (+0900) Subject: Refactor secure erase and add MMC erase engine X-Git-Tag: accepted/tizen/common/20170214.173822~6 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fsecurity%2Fode.git;a=commitdiff_plain;h=d92e8dee95eae202f9e45d41a2a6281ecf29bf82 Refactor secure erase and add MMC erase engine Change-Id: Ibfd5df003e1ec10ee2e1a34107eb341a7501f7c7 Signed-off-by: seolheui,kim --- diff --git a/rmi/secure-erase.h b/rmi/secure-erase.h index 48facda..2eb4735 100644 --- a/rmi/secure-erase.h +++ b/rmi/secure-erase.h @@ -34,12 +34,7 @@ public: int clean(const std::string& name); private: - int fileErase(const std::string& name); - int directoryErase(const std::string& name); - void dropCachePage(); -private: ODEControlContext& context; - std::string devicePath; }; } // namespace ode diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 6ec742a..c07f9e1 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -25,9 +25,10 @@ SET(SERVER_SRCS main.cpp kernel-keyring.cpp internal-encryption.cpp external-encryption.cpp - engine/ext4-engine.cpp - engine/dmcrypt-engine.cpp - engine/ecryptfs-engine.cpp + engine/encryption/ext4-engine.cpp + engine/encryption/dmcrypt-engine.cpp + engine/encryption/ecryptfs-engine.cpp + engine/erase/mmc-engine.cpp key-manager/key-store.cpp key-manager/key-manager.cpp key-manager/key-generator.cpp diff --git a/server/engine/dmcrypt-engine.cpp b/server/engine/encryption/dmcrypt-engine.cpp similarity index 99% rename from server/engine/dmcrypt-engine.cpp rename to server/engine/encryption/dmcrypt-engine.cpp index 8152d76..ce97023 100644 --- a/server/engine/dmcrypt-engine.cpp +++ b/server/engine/encryption/dmcrypt-engine.cpp @@ -24,8 +24,8 @@ #include #include -#include "../file-footer.h" -#include "../ext4-tool.h" +#include "../../file-footer.h" +#include "../../ext4-tool.h" #include "dmcrypt-engine.h" diff --git a/server/engine/dmcrypt-engine.h b/server/engine/encryption/dmcrypt-engine.h similarity index 100% rename from server/engine/dmcrypt-engine.h rename to server/engine/encryption/dmcrypt-engine.h diff --git a/server/engine/ecryptfs-engine.cpp b/server/engine/encryption/ecryptfs-engine.cpp similarity index 99% rename from server/engine/ecryptfs-engine.cpp rename to server/engine/encryption/ecryptfs-engine.cpp index cea2716..ece06ad 100644 --- a/server/engine/ecryptfs-engine.cpp +++ b/server/engine/encryption/ecryptfs-engine.cpp @@ -24,8 +24,8 @@ #include #include -#include "../kernel-keyring.h" -#include "../file-footer.h" +#include "../../kernel-keyring.h" +#include "../../file-footer.h" #include "ecryptfs-engine.h" diff --git a/server/engine/ecryptfs-engine.h b/server/engine/encryption/ecryptfs-engine.h similarity index 98% rename from server/engine/ecryptfs-engine.h rename to server/engine/encryption/ecryptfs-engine.h index 4a57f1f..983ed6d 100644 --- a/server/engine/ecryptfs-engine.h +++ b/server/engine/encryption/ecryptfs-engine.h @@ -20,7 +20,7 @@ #include #include -#include "../progress-bar.h" +#include "progress-bar.h" namespace ode { diff --git a/server/engine/ext4-engine.cpp b/server/engine/encryption/ext4-engine.cpp similarity index 99% rename from server/engine/ext4-engine.cpp rename to server/engine/encryption/ext4-engine.cpp index e04801a..0abd19c 100644 --- a/server/engine/ext4-engine.cpp +++ b/server/engine/encryption/ext4-engine.cpp @@ -33,8 +33,8 @@ #include #include -#include "../file-footer.h" -#include "../key-manager/key-generator.h" +#include "../../file-footer.h" +#include "../../key-manager/key-generator.h" #include "ext4-engine.h" diff --git a/server/engine/ext4-engine.h b/server/engine/encryption/ext4-engine.h similarity index 100% rename from server/engine/ext4-engine.h rename to server/engine/encryption/ext4-engine.h diff --git a/server/engine/erase/mmc-engine.cpp b/server/engine/erase/mmc-engine.cpp new file mode 100644 index 0000000..f9d84c6 --- /dev/null +++ b/server/engine/erase/mmc-engine.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "ext4-tool.h" +#include "block-device.h" +#include "mmc-engine.h" + +namespace ode { + +namespace { + +int getTotalFileCount(const std::string &path) +{ + int total = 0; + runtime::DirectoryIterator iter(path), end; + + while (iter != end) { + std::string next = path + "/" + iter->getName(); + runtime::File file(next); + if (!file.exists()) { + return -1; + } + + if (file.isFile()) { + total++; + } else if (file.isDirectory()) { + int subTotal = getTotalFileCount(next); + if (subTotal != -1) + total += subTotal; + } + ++iter; + } + return total; +} + +} /* namespace */ + +MMCEraseEngine::MMCEraseEngine(const ProgressBar &prgsBar) : + progressBar(prgsBar) +{ +} + +MMCEraseEngine::~MMCEraseEngine() +{ +} + +int MMCEraseEngine::cleanDevice(const std::string &path) +{ + runtime::File file(path, O_WRONLY); + if (!file.exists() || !file.isDevice()) { + throw runtime::Exception("Target doesn't exist"); + } + + BlockDevice blockDevice(path); + unsigned totalBlock, blockSize; + + Ext4Tool ext4Tool(path); + totalBlock = ext4Tool.getTotalBlockCount(); + blockSize = (unsigned int)blockDevice.getSize(); + + for (unsigned int i = 0; i < totalBlock; i++) { + if (!ext4Tool.isUsedBlock(i)) { + Block block(i * blockSize, blockSize); + blockDevice.discard(block); + } + progressBar.update(i, totalBlock, 1); + } + + progressBar.done(); + return 0; +} + +int MMCEraseEngine::eraseDevice(const std::string &path) +{ + runtime::File file(path, O_WRONLY); + if (!file.exists()) { + throw runtime::Exception("Target doesn't exist"); + } + + BlockDevice blockDevice(path); + Ext4Tool ext4Tool(blockDevice.getName()); + + unsigned int totalBlock = ext4Tool.getTotalBlockCount(); + unsigned int blockSize = (unsigned int)blockDevice.getSize(); + + for (unsigned int i = 0; i < totalBlock; i++) { + Block block(i * blockSize, blockSize); + blockDevice.discard(block); + progressBar.update(i, totalBlock, 1); + } + + progressBar.done(); + return 0; +} + +int MMCEraseEngine::eraseFile(const std::string &path) +{ + int ret = 0, fd = 0; + int extentBlockCount = 0; + char buf[4096] = ""; + struct fiemap *fmap = (struct fiemap *)buf; + struct fiemap_extent *fm_ext = NULL; + int count = (sizeof(buf) - sizeof(*fmap)) / sizeof(struct fiemap_extent); + + ::memset(fmap, 0, sizeof(struct fiemap)); + + fd = ::open(path.c_str(), O_RDONLY); + if (fd < 0) { + throw runtime::Exception("cannot open the file"); + } + + fmap->fm_length = ~0ULL; + fmap->fm_flags = 0; + fmap->fm_extent_count = count; + + ret = ::ioctl(fd, FS_IOC_FIEMAP, (unsigned long)fmap); + if (ret < 0) { + ::close(fd); + throw runtime::Exception("failed to get a fiemap"); + } + + ::close(fd); + + fm_ext = &fmap->fm_extents[0]; + extentBlockCount = (int)fmap->fm_mapped_extents; + + BlockDevice blockDevice(path); + for (int i = 0; i < extentBlockCount; i++) { + Block block(fm_ext[i].fe_physical, fm_ext[i].fe_length); + ret = blockDevice.secDiscard(block); + if (ret < 0) { + throw runtime::Exception("failed to erase the device"); + } + } + + if (totalFileCount == 1) { + progressBar.update(1, extentBlockCount, 1); + } + + return ret; +} + +int MMCEraseEngine::eraseDirectory(const std::string &path) +{ + runtime::DirectoryIterator iter(path), end; + + while (iter != end) { + std::string next = path + "/" + iter->getName(); + runtime::File file(next); + if (!file.exists()) { + throw runtime::Exception("Target doesn't exist"); + } + + if (file.isFile()) { + eraseFile(next); + ::remove(next.c_str()); + erasedFileCount++; + progressBar.update(erasedFileCount, totalFileCount, 1); + } else if (file.isDirectory()) { + eraseDirectory(next); + } + ++iter; + } + + eraseFile(path); + ::rmdir(path.c_str()); + return 0; +} + +int MMCEraseEngine::eraseFiles(const std::string &path) +{ + runtime::File file(path); + + if (!file.exists()) { + throw runtime::Exception("Target doesn't exist"); + } + + if (file.isFile()) { + totalFileCount = 1; + eraseFile(path); + ::remove(path.c_str()); + } else { + totalFileCount = getTotalFileCount(path); + erasedFileCount = 0; + eraseDirectory(path); + } + + progressBar.done(); + return 0; +} + +} /* namespace ode */ diff --git a/server/engine/erase/mmc-engine.h b/server/engine/erase/mmc-engine.h new file mode 100644 index 0000000..31990a0 --- /dev/null +++ b/server/engine/erase/mmc-engine.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +#ifndef __MMC_ERASE_ENGINE_H__ +#define __MMC_ERASE_ENGINE_H__ + +#include "progress-bar.h" + +namespace ode { + +class MMCEraseEngine final { +public: + MMCEraseEngine(const ProgressBar &prgsBar); + MMCEraseEngine(const MMCEraseEngine &) = delete; + MMCEraseEngine(MMCEraseEngine &&) = delete; + ~MMCEraseEngine(); + + MMCEraseEngine &operator=(const MMCEraseEngine &) = delete; + MMCEraseEngine &operator=(MMCEraseEngine &&) = delete; + + int eraseDevice(const std::string &path); + int cleanDevice(const std::string &path); + int eraseFiles(const std::string &path); + +private: + int eraseFile(const std::string &path); + int eraseDirectory(const std::string &path); +private: + ProgressBar progressBar; + int totalFileCount; + int erasedFileCount; +}; + +} /* namespace ode */ + +#endif /*__MMC_ERASE_ENGINE_H__*/ diff --git a/server/external-encryption.cpp b/server/external-encryption.cpp index 79001d3..173323a 100644 --- a/server/external-encryption.cpp +++ b/server/external-encryption.cpp @@ -33,7 +33,7 @@ #include "launchpad.h" #include "app-bundle.h" #include "progress-bar.h" -#include "engine/ecryptfs-engine.h" +#include "engine/encryption/ecryptfs-engine.h" #include "key-manager/key-manager.h" #include "rmi/external-encryption.h" diff --git a/server/internal-encryption.cpp b/server/internal-encryption.cpp index 284e436..f294f20 100644 --- a/server/internal-encryption.cpp +++ b/server/internal-encryption.cpp @@ -29,7 +29,7 @@ #include "vconf.h" #include "progress-bar.h" -#include "engine/dmcrypt-engine.h" +#include "engine/encryption/dmcrypt-engine.h" #include "key-manager/key-manager.h" #include "rmi/internal-encryption.h" diff --git a/server/secure-erase.cpp b/server/secure-erase.cpp index e8b66ad..2a46a25 100644 --- a/server/secure-erase.cpp +++ b/server/secure-erase.cpp @@ -14,69 +14,48 @@ * limitations under the License */ #include - -#include -#include -#include -#include - #include -#include -#include -#include +#include -#include "ext4-tool.h" -#include "block-device.h" -#include "progress-bar.h" +#include "engine/erase/mmc-engine.h" #include "rmi/secure-erase.h" +#define ERASE_ENGINE MMCEraseEngine #define PRIVILEGE_PLATFORM "http://tizen.org/privilege/internal/default/platform" namespace ode { namespace { -std::unique_ptr progressBar; +std::unique_ptr engine; -static int totalFileCount = 0; -static int erasedFileCount = 0; - -static int getTotalFileCount(const std::string &name) +void dropCachePage(void) { - int total = 0; - runtime::DirectoryIterator iter(name), end; - - while (iter != end) { - std::string next = name + "/" + iter->getName(); - runtime::File file(next); - if (!file.exists()) { - return -1; - } - - if (file.isFile()) { - total++; - } else if (file.isDirectory()) { - int subTotal = getTotalFileCount(next); - if (subTotal != -1) - total += subTotal; - } - ++iter; + std::ofstream file; + + file.open("/proc/sys/vm/drop_caches"); + if (file.fail()) { + throw runtime::Exception("failed to access drop_caches file"); } - return total; + file << "3\n"; + file.close(); + ::sync(); + return; } } /* namespace */ SecureErase::SecureErase(ODEControlContext &ctx) : - context(ctx), devicePath("") + context(ctx) { context.expose(this, PRIVILEGE_PLATFORM, (int)(SecureErase::erase)(std::string)); context.expose(this, PRIVILEGE_PLATFORM, (int)(SecureErase::clean)(std::string)); - progressBar.reset(new ProgressBar([](int v) { - ::vconf_set_str(VCONFKEY_ODE_ERASE_PROGRESS, std::to_string(v).c_str()); - })); + engine.reset(new ERASE_ENGINE(ProgressBar([](int v) { + ::vconf_set_str(VCONFKEY_ODE_ERASE_PROGRESS, std::to_string(v).c_str()); + })) + ); } SecureErase::~SecureErase() @@ -88,30 +67,12 @@ int SecureErase::erase(const std::string &name) auto eraseWorker = [name, this]() { try { runtime::File file(name); - - BlockDevice blockDevice(name); - devicePath = blockDevice.getName(); - - if (file.isFile()) { - totalFileCount = 1; - fileErase(name); - } else if (file.isDirectory()) { - totalFileCount = getTotalFileCount(name); - erasedFileCount = 0; - directoryErase(name); - } else if (file.isDevice()) { - Ext4Tool ext4Tool(name); - unsigned int totalBlock = ext4Tool.getTotalBlockCount(); - unsigned int blockSize = (unsigned int)blockDevice.getSize(); - - for (unsigned int i = 0; i < totalBlock; i++) { - Block block(i * blockSize, blockSize); - blockDevice.discard(block); - progressBar->update(i, totalBlock, 1); - } + if (file.isDevice()) { + engine->eraseDevice(name); + } else { + engine->eraseFiles(name); } dropCachePage(); - progressBar->done(); } catch (runtime::Exception &e) {} }; @@ -123,129 +84,16 @@ int SecureErase::erase(const std::string &name) int SecureErase::clean(const std::string &name) { - try { - runtime::File file(name, O_WRONLY); - if (!file.exists() || !file.isDevice()) - return -1; - } catch (runtime::Exception &e) {} - auto cleanWorker = [name, this]() { try { - BlockDevice blockDevice(name); - unsigned totalBlock, blockSize; - - Ext4Tool ext4Tool(name); - totalBlock = ext4Tool.getTotalBlockCount(); - blockSize = (unsigned int) blockDevice.getSize(); - - for (unsigned int i = 0; i < totalBlock; i++) { - if (!ext4Tool.isUsedBlock(i)) { - Block block(i * blockSize, blockSize); - blockDevice.discard(block); - } - - progressBar->update(i, totalBlock, 1); - } + engine->cleanDevice(name); dropCachePage(); - progressBar->done(); } catch (runtime::Exception &e) {} }; std::thread asyncWork(cleanWorker); asyncWork.detach(); - - return 0; -} - -int SecureErase::fileErase(const std::string &name) -{ - int ret = 0, fd = 0; - int extentBlockCount = 0; - char buf[4096] = ""; - struct fiemap *fmap = (struct fiemap *)buf; - struct fiemap_extent *fm_ext = NULL; - int count = (sizeof(buf) - sizeof(*fmap)) / sizeof(struct fiemap_extent); - - /* [TBD] stop the related process */ - - BlockDevice blockDevice(devicePath); - - ::memset(fmap, 0, sizeof(struct fiemap)); - - fd = ::open(name.c_str(), O_RDONLY); - if (fd < 0) { - return -1; - } - - fmap->fm_length = ~0ULL; - fmap->fm_flags = 0; - fmap->fm_extent_count = count; - - ret = ::ioctl(fd, FS_IOC_FIEMAP, (unsigned long)fmap); - if (ret < 0) { - ::close(fd); - return -1; - } - - ::close(fd); - - fm_ext = &fmap->fm_extents[0]; - extentBlockCount = (int)fmap->fm_mapped_extents; - - for (int i = 0; i < extentBlockCount; i++) { - Block block(fm_ext[i].fe_physical, fm_ext[i].fe_length); - ret = blockDevice.secDiscard(block); - if (ret < 0) { - return -1; - } - - if (totalFileCount == 1) { - progressBar->update(i, extentBlockCount, 1); - } - } - - return ret; -} - -int SecureErase::directoryErase(const std::string &name) -{ - runtime::DirectoryIterator iter(name), end; - while (iter != end) { - std::string next = name + "/" + iter->getName(); - runtime::File file(next); - if (!file.exists()) { - return -1; - } - - if (file.isFile()) { - fileErase(next); - ::remove(next.c_str()); - erasedFileCount++; - progressBar->update(erasedFileCount, totalFileCount, 1); - } else if (file.isDirectory()) { - directoryErase(next); - } - ++iter; - } - - fileErase(name); - ::rmdir(name.c_str()); return 0; } -void SecureErase::dropCachePage() -{ - std::ofstream file; - - file.open("/proc/sys/vm/drop_caches"); - if (file.fail()) { - throw runtime::Exception("Failed to access drop_caches file"); - } - file << "3\n"; - file.close(); - ::sync(); - - return; -} - } // namespace ode diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b7b8bc5..a9d1c08 100755 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -22,8 +22,8 @@ SET(TEST_SRC main.cpp af.cpp ../server/file-footer.cpp ../server/kernel-keyring.cpp - ../server/engine/ext4-engine.cpp - ../server/engine/ecryptfs-engine.cpp + ../server/engine/encryption/ext4-engine.cpp + ../server/engine/encryption/ecryptfs-engine.cpp ../server/key-manager/key-generator.cpp ../server/key-manager/anti-forensics.cpp ../server/ext4-tool.cpp diff --git a/tests/dmcrypt-engine.cpp b/tests/dmcrypt-engine.cpp index 7fecded..e5ff644 100644 --- a/tests/dmcrypt-engine.cpp +++ b/tests/dmcrypt-engine.cpp @@ -29,7 +29,7 @@ #include #include -#include "../server/engine/dmcrypt-engine.cpp" +#include "../server/engine/encryption/dmcrypt-engine.cpp" #define TEST_USERDATA_NAME "userdata" #define TEST_USERDATA_PATH "/opt/usr" diff --git a/tests/ecryptfs-engine.cpp b/tests/ecryptfs-engine.cpp index a35f83e..6d13631 100644 --- a/tests/ecryptfs-engine.cpp +++ b/tests/ecryptfs-engine.cpp @@ -18,7 +18,7 @@ #include #include -#include "../server/engine/ecryptfs-engine.h" +#include "../server/engine/encryption/ecryptfs-engine.h" #define TEST_PATH "/opt/usr" diff --git a/tests/ext4-engine.cpp b/tests/ext4-engine.cpp index 9e89612..d0efba5 100755 --- a/tests/ext4-engine.cpp +++ b/tests/ext4-engine.cpp @@ -18,7 +18,7 @@ #include #include -#include "../server/engine/ext4-engine.h" +#include "../server/engine/encryption/ext4-engine.h" #define TEST_PATH "/opt/usr"