From: s414kim Date: Wed, 30 Aug 2017 11:43:39 +0000 (+0900) Subject: Add default secure-erase engine X-Git-Tag: submit/tizen_4.0/20170922.051801~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e6f8a79aeeedca180f24158255d538c1efc53e4b;p=platform%2Fcore%2Fsecurity%2Fode.git Add default secure-erase engine Change-Id: Ib7e8ff2fe11f41975d34affc47e85b1ee473bdd7 Signed-off-by: s414kim --- diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 66e7a4a..ee73f4c 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -22,7 +22,6 @@ SET(SERVER_SRCS main.cpp file-footer.cpp secure-erase.cpp progress-bar.cpp - block-device.cpp kernel-keyring.cpp internal-encryption.cpp external-encryption.cpp @@ -32,6 +31,7 @@ SET(SERVER_SRCS main.cpp engine/encryption/ecryptfs-engine.cpp engine/encryption/cryptsetup-engine.cpp engine/erase/mmc-engine.cpp + engine/erase/erase-engine.cpp key-manager/key-store.cpp key-manager/key-manager.cpp key-manager/key-generator.cpp diff --git a/server/block-device.cpp b/server/block-device.cpp deleted file mode 100644 index e04de25..0000000 --- a/server/block-device.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 2015 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 "block-device.h" - -namespace ode { - -BlockDevice::BlockDevice(const std::string &path) : name(""), blockSize(0) -{ - int ret = 0; - runtime::File file(path); - if (!file.exists()) { - throw runtime::Exception("target doesn't exist"); - } - - if (!file.isDevice()) { - createDeviceList(); - evaluateDevice(path); - } else { - name = path; - } - - if (name != "") { - int descriptor = ::open(name.c_str(), O_RDONLY); - if (descriptor > 0) { - ret = ::ioctl(descriptor, FIGETBSZ, &blockSize); - if (ret < 0) { - ::close(descriptor); - throw runtime::Exception("Failed to get block size"); - } - } - ::close(descriptor); - } else { - throw runtime::Exception("Cannot find device name"); - } -} - -BlockDevice::~BlockDevice() -{ -} - -int BlockDevice::open(int flags) -{ - int descriptor = 0; - - if (name != "") { - descriptor = ::open(name.c_str(), flags); - return descriptor; - } - - return -1; -} - -void BlockDevice::close(int descriptor) -{ - int ret = 0; - - ret = ::close(descriptor); - if (ret < 0) { - throw runtime::Exception("Cannot close descriptor"); - } - return; -} - -int BlockDevice::discard(off_t offset, off_t length) -{ - int devFd = 0; - unsigned long long range[2]; - - devFd = BlockDevice::open(O_WRONLY); - if (devFd < 0) { - return -1; - } - - range[0] = (unsigned long long)offset; - range[1] = (unsigned long long)length; - - int ret = ::ioctl(devFd, BLKDISCARD, &range); - - BlockDevice::close(devFd); - - return ret; -} - -int BlockDevice::secDiscard(off_t offset, off_t length) -{ - int devFd = 0; - unsigned long long range[2]; - - devFd = BlockDevice::open(O_WRONLY); - if (devFd < 0) { - return -1; - } - - range[0] = (unsigned long long)offset; - range[1] = (unsigned long long)length; - - int ret = ::ioctl(devFd, BLKSECDISCARD, &range); - - BlockDevice::close(devFd); - - return ret; -} - -const std::string &BlockDevice::getName() const -{ - if (name == "") { - throw runtime::Exception("Cannot get device name"); - } - return name; -} - -blksize_t BlockDevice::getBlockSize() -{ - if (name == "") { - throw runtime::Exception("Cannot get device name"); - } - return blockSize; -} - -void BlockDevice::createDeviceList() -{ - char deviceName[PATH_MAX] = ""; - char source[PATH_MAX] = ""; - char filesystemType[PATH_MAX] = ""; - std::string deviceInfo = ""; - - std::ifstream file("/etc/mtab"); - if (file.fail()) { - throw runtime::Exception("/etc/mtab doesn't exist"); - } - - while (std::getline(file, deviceInfo)) { - if (::sscanf(deviceInfo.c_str(), "%s %s %s %*s %*d %*d", - deviceName, source, filesystemType) == 3) { - int fd = ::open(deviceName, O_WRONLY); - if (fd < 0) { - continue; - } - - if (strcmp(filesystemType, "ext2") && strcmp(filesystemType, "ext3") - && strcmp(filesystemType, "ext4")) { - ::close(fd); - continue; - } - - runtime::File device(deviceName); - if (!device.exists()) { - ::close(fd); - continue; - } - - if (device.isDevice()) { - deviceList.insert(std::make_pair(source, deviceName)); - } - ::close(fd); - } - } - - return; -} - -void BlockDevice::evaluateDevice(const std::string &path) -{ - DeviceListIterator matchedDevice = deviceList.find(path); - const std::string &subStr = path; - std::size_t pos = subStr.size(); - - if (matchedDevice != deviceList.end()) { - name = matchedDevice->second; - return; - } - - while ((pos = subStr.rfind('/', pos - 1)) != std::string::npos && pos != 0) { - std::string subPath = subStr.substr(0, pos); - matchedDevice = deviceList.find(subPath); - if (matchedDevice != deviceList.end()) { - name = matchedDevice->second; - return; - } - } -} - -} //namespace ode diff --git a/server/block-device.h b/server/block-device.h deleted file mode 100644 index 13e6546..0000000 --- a/server/block-device.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2015 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 __BLOCK_DEVICE_H__ -#define __BLOCK_DEVICE_H__ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace ode { - -class BlockDevice final { -public: - typedef std::unordered_map DeviceList; - typedef DeviceList::const_iterator DeviceListIterator; - - BlockDevice(const std::string &path); - BlockDevice(const BlockDevice &) = delete; - BlockDevice(BlockDevice &&) = delete; - ~BlockDevice(); - - BlockDevice &operator=(const BlockDevice &) = delete; - BlockDevice &operator=(BlockDevice &&) = delete; - - int open(int flags); - void close(int descriptor); - - int discard(off_t offset, off_t length); - int secDiscard(off_t offset, off_t length); - - const std::string &getName() const; - blksize_t getBlockSize(); - -private: - void createDeviceList(); - void evaluateDevice(const std::string &path); - -private: - std::string name; - blksize_t blockSize; - - DeviceList deviceList; -}; - -} // namespace ode - -#endif /* __BLOCK_DEVICE_H__ */ diff --git a/server/engine/erase/erase-engine.cpp b/server/engine/erase/erase-engine.cpp new file mode 100644 index 0000000..a6824b5 --- /dev/null +++ b/server/engine/erase/erase-engine.cpp @@ -0,0 +1,72 @@ +/* + * + * 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 "erase-engine.h" + +#define ERASE_SIZE 4096 + +namespace ode { + +EraseEngine::EraseEngine(const ProgressBar &prgsBar) : + progressBar(prgsBar), target("") +{ +} + +EraseEngine::~EraseEngine() +{ +} + +void EraseEngine::discardBlock(unsigned long long offset, blksize_t size) +{ + char zeros[ERASE_SIZE] = ""; + if (size > ERASE_SIZE) { + throw runtime::Exception("[eraseBlock] : size is too big"); + } + + runtime::File zero("/dev/zero"); + zero.open(O_RDONLY); + zero.read(zeros, sizeof(zeros)); + zero.close(); + + runtime::File device(target); + device.open(O_WRONLY); + device.lseek(offset, SEEK_SET); + device.write(zeros, size); + device.close(); +} + +void EraseEngine::cleanDevice(const std::string &path) +{ + blkcnt_t totalBlockCount = 0; + blksize_t blockSize = 0; + unsigned long long offset = 0; + target = path; + + Ext4Tool ext4Tool(target); + totalBlockCount = (blkcnt_t)ext4Tool.getTotalBlockCount(); + blockSize = (blksize_t)ext4Tool.getBlockSize(); + + for (blkcnt_t i = 0; i < totalBlockCount; i++) { + if (!ext4Tool.isUsedBlock(i)) { + offset = (unsigned long long)i * (unsigned long long)blockSize; + discardBlock(offset, blockSize); + } + progressBar.update(i, totalBlockCount, 1); + } + progressBar.done(); +} + +} /* namespace ode */ diff --git a/server/engine/erase/erase-engine.h b/server/engine/erase/erase-engine.h new file mode 100644 index 0000000..2ad61dd --- /dev/null +++ b/server/engine/erase/erase-engine.h @@ -0,0 +1,55 @@ +/* + * + * 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 __ERASE_ENGINE_H__ +#define __ERASE_ENGINE_H__ + +#include +#include +#include +#include +#include +#include +#include + +#include "logger.h" +#include "ext4-tool.h" +#include "progress-bar.h" + +namespace ode { + +class EraseEngine { +public: + EraseEngine(const ProgressBar &prgsBar); + EraseEngine(const EraseEngine &) = delete; + EraseEngine(EraseEngine &&) = delete; + ~EraseEngine(); + + EraseEngine &operator=(const EraseEngine &) = delete; + EraseEngine &operator=(EraseEngine &&) = delete; + + void cleanDevice(const std::string &path); +private: + void discardBlock(unsigned long long offset, blksize_t size); +private: + ProgressBar progressBar; + std::string target; +}; + +} /* namespace ode */ + +#endif /*__ERASE_ENGINE_H__*/ diff --git a/server/engine/erase/mmc-engine.cpp b/server/engine/erase/mmc-engine.cpp index 44cbbf1..70cec3d 100644 --- a/server/engine/erase/mmc-engine.cpp +++ b/server/engine/erase/mmc-engine.cpp @@ -1,4 +1,5 @@ /* + * * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,54 +15,12 @@ * limitations under the License */ -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "logger.h" -#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), totalFileCount(0), erasedFileCount(0) + progressBar(prgsBar), target("") { } @@ -69,145 +28,59 @@ MMCEraseEngine::~MMCEraseEngine() { } -int MMCEraseEngine::cleanDevice(const std::string &path) +void MMCEraseEngine::synchronization(void) { - BlockDevice blockDevice(path); - blkcnt_t totalBlock; - blksize_t blockSize; - Ext4Tool ext4Tool(blockDevice.getName()); - - totalBlock = (blkcnt_t)ext4Tool.getTotalBlockCount(); - blockSize = blockDevice.getBlockSize(); - - for (blkcnt_t i = 0; i < totalBlock; i++) { - if (!ext4Tool.isUsedBlock(i)) { - blockDevice.discard(i*blockSize, blockSize); - } - progressBar.update(i, totalBlock, 1); + std::ofstream file; + ::sync(); + file.open("/proc/sys/vm/drop_caches"); + if (file.fail()) { + throw runtime::Exception("failed to access drop_caches file"); } - - progressBar.done(); - return 0; + file << "3\n"; + file.close(); + return; } -int MMCEraseEngine::eraseDevice(const std::string &path) +void MMCEraseEngine::discardBlock(unsigned long long offset, blksize_t size) { - blkcnt_t totalBlock; - blksize_t blockSize; + int descriptor = 0, ret = 0; + unsigned long long range[2] = {0, }; - runtime::File file(path, O_WRONLY); - if (!file.exists()) { - throw runtime::Exception("Target doesn't exist"); + descriptor = ::open(target.c_str(), O_WRONLY); + if (descriptor < 0) { + throw runtime::Exception("Cannot open the target"); } - BlockDevice blockDevice(path); - Ext4Tool ext4Tool(blockDevice.getName()); - - totalBlock = ext4Tool.getTotalBlockCount(); - blockSize = blockDevice.getBlockSize(); - - for (blkcnt_t i = 0; i < totalBlock; i++) { - blockDevice.discard(i * blockSize, blockSize); - progressBar.update(i, totalBlock, 1); - } - - progressBar.done(); - return 0; -} + range[0] = offset; + range[1] = (unsigned long long)size; -int MMCEraseEngine::eraseFile(const std::string &path) -{ - int ret = 0, fd = 0; - blkcnt_t 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); + ret = ::ioctl(descriptor, BLKDISCARD, &range); + ::close(descriptor); 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 (blkcnt_t i = 0; i < extentBlockCount; i++) { - ret = blockDevice.secDiscard(fm_ext[i].fe_physical, fm_ext[i].fe_length); - if (ret < 0) { - throw runtime::Exception("failed to erase the device"); - } - } - - if (totalFileCount == 1) { - progressBar.update(1, extentBlockCount, 1); + throw runtime::Exception("Failed to secure discard the device"); } - - return ret; } -int MMCEraseEngine::eraseDirectory(const std::string &path) +void MMCEraseEngine::cleanDevice(const std::string &path) { - runtime::DirectoryIterator iter(path), end; + blkcnt_t totalBlockCount = 0; + blksize_t blockSize = 0; + unsigned long long offset = 0; + target.append(path); - while (iter != end) { - std::string next = path + "/" + iter->getName(); - runtime::File file(next); - if (!file.exists()) { - throw runtime::Exception("Target doesn't exist"); - } + Ext4Tool ext4Tool(target); + totalBlockCount = (blkcnt_t)ext4Tool.getTotalBlockCount(); + blockSize = (blksize_t)ext4Tool.getBlockSize(); - if (file.isFile()) { - eraseFile(next); - ::remove(next.c_str()); - erasedFileCount++; - progressBar.update(erasedFileCount, totalFileCount, 1); - } else if (file.isDirectory()) { - eraseDirectory(next); + for (blkcnt_t i = 0; i < totalBlockCount; i++) { + if (!ext4Tool.isUsedBlock(i)) { + offset = (unsigned long long)i * (unsigned long long)blockSize; + discardBlock(offset, blockSize); } - ++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"); + progressBar.update(i, totalBlockCount, 1); } - - if (file.isFile()) { - totalFileCount = 1; - eraseFile(path); - ::remove(path.c_str()); - } else { - totalFileCount = getTotalFileCount(path); - erasedFileCount = 0; - eraseDirectory(path); - } - progressBar.done(); - return 0; + synchronization(); } } /* namespace ode */ diff --git a/server/engine/erase/mmc-engine.h b/server/engine/erase/mmc-engine.h index 31990a0..f6f969e 100644 --- a/server/engine/erase/mmc-engine.h +++ b/server/engine/erase/mmc-engine.h @@ -1,4 +1,5 @@ /* + * * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,11 +18,24 @@ #ifndef __MMC_ERASE_ENGINE_H__ #define __MMC_ERASE_ENGINE_H__ +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "logger.h" +#include "ext4-tool.h" #include "progress-bar.h" namespace ode { -class MMCEraseEngine final { +class MMCEraseEngine { public: MMCEraseEngine(const ProgressBar &prgsBar); MMCEraseEngine(const MMCEraseEngine &) = delete; @@ -31,17 +45,13 @@ public: 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); - + void cleanDevice(const std::string &target); private: - int eraseFile(const std::string &path); - int eraseDirectory(const std::string &path); + void synchronization(void); + void discardBlock(unsigned long long offset, blksize_t size); private: ProgressBar progressBar; - int totalFileCount; - int erasedFileCount; + std::string target; }; } /* namespace ode */ diff --git a/server/secure-erase.cpp b/server/secure-erase.cpp index 2a46a25..fe0e362 100644 --- a/server/secure-erase.cpp +++ b/server/secure-erase.cpp @@ -1,4 +1,5 @@ /* + * * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,33 +18,77 @@ #include #include +#include "ext4-tool.h" +#include "engine/erase/erase-engine.h" #include "engine/erase/mmc-engine.h" #include "rmi/secure-erase.h" -#define ERASE_ENGINE MMCEraseEngine +#define ERASE_ENGINE EraseEngine #define PRIVILEGE_PLATFORM "http://tizen.org/privilege/internal/default/platform" namespace ode { namespace { +typedef std::unordered_map DeviceList; std::unique_ptr engine; -void dropCachePage(void) +const std::string evaluateTarget(const std::string &path) { - std::ofstream file; + DeviceList deviceList; + DeviceList::const_iterator deviceListIter; + std::string subStr(path); + subStr.append("//"); + std::size_t pos = 0; + std::string mountInfo; + std::string name; + std::string source; + std::string type; + + runtime::File resource(path); + if (!resource.exists()) { + throw runtime::Exception("target doesn't exist"); + } - file.open("/proc/sys/vm/drop_caches"); + std::ifstream file("/etc/mtab"); if (file.fail()) { - throw runtime::Exception("failed to access drop_caches file"); + throw runtime::Exception("failed to access /etc/mtab"); } - file << "3\n"; - file.close(); - ::sync(); - return; -} + while (std::getline(file, mountInfo)) { + pos = mountInfo.find(" "); + name = mountInfo.substr(0, pos); + mountInfo.erase(0, pos+1); + + pos = mountInfo.find(" "); + source = mountInfo.substr(0, pos); + mountInfo.erase(0, pos+1); + + pos = mountInfo.find(" "); + type = mountInfo.substr(0, pos); + if (!type.compare("ext2") && !type.compare("ext3") + && !type.compare("ext4")) { + continue; + } + runtime::File device(name); + if (!device.exists()) { + continue; + } + if (device.isDevice()) { + deviceList.insert(std::make_pair(source, name)); + } + } + pos = subStr.size(); + while ((pos = subStr.rfind('/', pos - 1)) != std::string::npos && pos != 0) { + std::string subPath = subStr.substr(0, pos); + deviceListIter = deviceList.find(subPath); + if (deviceListIter != deviceList.end()) { + return deviceListIter->second; + } + } + return ""; +} } /* namespace */ SecureErase::SecureErase(ODEControlContext &ctx) : @@ -62,17 +107,12 @@ SecureErase::~SecureErase() { } + + int SecureErase::erase(const std::string &name) { auto eraseWorker = [name, this]() { try { - runtime::File file(name); - if (file.isDevice()) { - engine->eraseDevice(name); - } else { - engine->eraseFiles(name); - } - dropCachePage(); } catch (runtime::Exception &e) {} }; @@ -86,8 +126,9 @@ int SecureErase::clean(const std::string &name) { auto cleanWorker = [name, this]() { try { - engine->cleanDevice(name); - dropCachePage(); + std::string target; + target = evaluateTarget(name); + engine->cleanDevice(target); } catch (runtime::Exception &e) {} };