From ca1b3b3078202c243a890fcb75e60591ac2f2315 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Tue, 27 Oct 2020 12:14:10 +0100 Subject: [PATCH] refactoring: extract common file operations to StorageBackendSerialized Change-Id: I0a3fd26342482d747f44aae08ece46bb2b40a4fc --- Makefile.am | 1 + src/internal/storage_backend_flatbuffers.cpp | 114 ---------------------- src/internal/storage_backend_flatbuffers.hpp | 4 +- src/internal/storage_backend_serialized.cpp | 136 +++++++++++++++++++++++++++ src/internal/storage_backend_serialized.hpp | 60 +++++++++++- 5 files changed, 197 insertions(+), 118 deletions(-) create mode 100644 src/internal/storage_backend_serialized.cpp diff --git a/Makefile.am b/Makefile.am index 0c88727..1848ecd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -66,6 +66,7 @@ COMMON_SRC =\ src/internal/serializer_flatbuffers.cpp \ src/internal/print_content.cpp \ src/internal/storage_backend_flatbuffers.cpp \ + src/internal/storage_backend_serialized.cpp \ src/internal/storage_backend_xml.cpp src_libdbuspolicy1_la_SOURCES =\ diff --git a/src/internal/storage_backend_flatbuffers.cpp b/src/internal/storage_backend_flatbuffers.cpp index b0c6933..4867185 100644 --- a/src/internal/storage_backend_flatbuffers.cpp +++ b/src/internal/storage_backend_flatbuffers.cpp @@ -16,29 +16,16 @@ #include "include/fb_generated.h" #include "print_content.hpp" #include "serialized_convert.hpp" -#include "serializer.hpp" #include "storage_backend_flatbuffers.hpp" -#include "transaction_guard.hpp" #include "tslog.hpp" #include -#include -#include -#include #include -#include -#include -#include -#include using namespace FB; using ldp_xml_parser::MatchItemSend; namespace ldp_serialized { -// Set max size of serialized file to prevent mmap with unexpected memory size. -// 1MB. Adjustable -#define MAX_SFILE_SIZE (1024 * 1024) - typedef boost::tokenizer> tokenizer; template @@ -124,20 +111,10 @@ ldp_xml_parser::DecisionItem getDecisionItemMaybeNull(const T &item, const P *po } // anonymous namespace class StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl { - int fd{-1}; - uint8_t *mem{static_cast(MAP_FAILED)}; - size_t length{0}; const FB::File *file{nullptr}; - std::unique_ptr serializer; - - void releaseMMap(); - void releaseFD(); - public: - bool init(const char *filename, bool verify); bool initFromData(const uint8_t *mem, size_t size, bool verify); - bool initFromXML(const char *config_name); void release(); ldp_xml_parser::DecisionItem getDecisionFromSendIndex(const MatchItemSend &item, const FB::PolicySend *policy); @@ -217,79 +194,10 @@ ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::StorageBackendFlatbuffer return ldp_xml_parser::DecisionItem(ldp_xml_parser::Decision::ANY); } -void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::releaseMMap() { - assert(MAP_FAILED != mem); - assert(0 != length); - - if (munmap(mem, length) != 0) - tslog::log_error("munmap(): ", tslog::print_errno(errno), "\n"); - - mem = static_cast(MAP_FAILED); - length = 0; -} - -void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::releaseFD() { - assert(-1 != fd); - - if (close(fd) != 0) - tslog::log_error("close(): ", tslog::print_errno(errno), "\n"); - - fd = -1; -} - void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::release() { - if (-1 != fd) { // we need to check it, because we may have initialized the storage directly from File * - releaseMMap(); - releaseFD(); - } - - if (nullptr != serializer.get()) { - serializer.reset(nullptr); - } - file = nullptr; } -bool StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::init(const char *filename, bool verify) { - assert(nullptr == file); - - auto err = [filename] (const char *what) { - tslog::log_error("Can't ", what, " ", filename, ": ", tslog::print_errno(errno), "\n"); - return false; - }; - - fd = open(filename, O_RDONLY); - if (-1 == fd) - return err("open"); - - auto openGuard = transaction_guard::makeGuard([&] () { releaseFD(); }); - - struct stat buf; - - if (fstat(fd, &buf) == -1) - return err("stat"); - - length = buf.st_size; - if (length > MAX_SFILE_SIZE) { - tslog::log_error("Serialized file size(", length, ") is too large. (>", MAX_SFILE_SIZE, ") bytes.\n"); - return false; - } - - mem = reinterpret_cast(mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0)); - if (MAP_FAILED == mem) - return err("mmap"); - - auto mmapGuard = transaction_guard::makeGuard([&] () { releaseMMap(); }); - - if (!initFromData(mem, length, verify)) - return false; - - openGuard.dismiss(); - mmapGuard.dismiss(); - - return true; -} - bool StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::initFromData(const uint8_t *mem, size_t size, bool verify) { assert(nullptr == file); @@ -314,20 +222,6 @@ bool StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::initFromData(cons return file != nullptr; } -bool StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::initFromXML(const char *config_name) { - assert(nullptr == file); - assert(nullptr == serializer.get()); - - serializer.reset(new ldp_serializer::Serializer()); - - size_t serialized_size; - auto data = serializer->serialize(config_name, serialized_size); - if (nullptr == data) - return false; - - return initFromData(data, serialized_size, false); -} - void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::printContent(const bool xml_format) const { print_content::use_xml_format(xml_format); std::cerr << *file; @@ -353,18 +247,10 @@ TYPE_HELPER(Send, send) TYPE_HELPER(Receive, receive) TYPE_HELPER(Access, access) -bool StorageBackendFlatbuffers::init(const char *filename, bool verify) { - return pimpl->init(filename, verify); -} - bool StorageBackendFlatbuffers::initFromData(const uint8_t *serialized_data, size_t length, bool verify) { return pimpl->initFromData(serialized_data, length, verify); } -bool StorageBackendFlatbuffers::initFromXML(const char *config_name) { - return pimpl->initFromXML(config_name); -} - void StorageBackendFlatbuffers::release() { pimpl->release(); } diff --git a/src/internal/storage_backend_flatbuffers.hpp b/src/internal/storage_backend_flatbuffers.hpp index aaba006..6bdd707 100644 --- a/src/internal/storage_backend_flatbuffers.hpp +++ b/src/internal/storage_backend_flatbuffers.hpp @@ -28,9 +28,7 @@ public: StorageBackendFlatbuffers(); ~StorageBackendFlatbuffers(); - bool init(const char *filename, bool verify = false); - bool initFromData(const uint8_t *serialized_data, size_t length, bool verify = false); - bool initFromXML(const char *config_name); + bool initFromData(const uint8_t *serialized_data, size_t length, bool verify); void release(); void printContent(const bool xml_format = false) const; diff --git a/src/internal/storage_backend_serialized.cpp b/src/internal/storage_backend_serialized.cpp new file mode 100644 index 0000000..f9fb54f --- /dev/null +++ b/src/internal/storage_backend_serialized.cpp @@ -0,0 +1,136 @@ +/* MIT License + * + * Copyright (c) 2019-2020 Samsung Electronics Co., Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ + +#include "storage_backend_serialized.hpp" +#include "transaction_guard.hpp" +#include "tslog.hpp" +#include +#include +#include +#include +#include +#include + +using namespace ldp_serialized; + +const size_t StorageBackendSerialized::MAX_SFILE_SIZE; + +StorageBackendSerialized::StorageBackendSerialized() +: __mem{static_cast(MAP_FAILED)} +{ +} + +StorageBackendSerialized::~StorageBackendSerialized() { + if (-1 != __fd) { + releaseMMap(); + releaseFD(); + } +} + +bool StorageBackendSerialized::init(const char *filename, bool verify) +{ + auto err = [filename] (const char *what) { + tslog::log_error("Can't ", what, " ", filename, ": ", tslog::print_errno(errno), "\n"); + return false; + }; + + __fd = open(filename, O_RDONLY); + if (-1 == __fd) + return err("open"); + + auto openGuard = transaction_guard::makeGuard([&] () { releaseFD(); }); + + struct stat buf; + + if (fstat(__fd, &buf) == -1) + return err("stat"); + + __length = buf.st_size; + if (__length > MAX_SFILE_SIZE) { + tslog::log_error("Serialized file size(", __length, ") is too large. (>", MAX_SFILE_SIZE, ") bytes.\n"); + return false; + } + + __mem = reinterpret_cast(mmap(NULL, __length, PROT_READ, MAP_PRIVATE, __fd, 0)); + if (MAP_FAILED == __mem) + return err("mmap"); + + auto mmapGuard = transaction_guard::makeGuard([&] () { releaseMMap(); }); + + if (!initFromData(__mem, __length, verify)) + return false; + + openGuard.dismiss(); + mmapGuard.dismiss(); + + return true; +} + +bool StorageBackendSerialized::initFromData(const uint8_t *serialized_data, size_t length, bool verify) +{ + return impl.initFromData(serialized_data, length, verify); +} + +void StorageBackendSerialized::releaseMMap() { + assert(MAP_FAILED != __mem); + assert(0 != __length); + + if (munmap(__mem, __length) != 0) + tslog::log_error("munmap(): ", tslog::print_errno(errno), "\n"); + + __mem = static_cast(MAP_FAILED); + __length = 0; +} + +bool StorageBackendSerialized::initFromXML(const char *config_name) { + assert(nullptr == serializer.get()); + + serializer.reset(new ldp_serializer::Serializer()); + + size_t serialized_size; + auto data = serializer->serialize(config_name, serialized_size); + if (nullptr == data) + return false; + + return initFromData(data, serialized_size, false); +} + +void StorageBackendSerialized::releaseFD() { + assert(-1 != __fd); + + if (close(__fd) != 0) + tslog::log_error("close(): ", tslog::print_errno(errno), "\n"); + + __fd = -1; +} + +void StorageBackendSerialized::release() { + if (-1 != __fd) { + releaseMMap(); + releaseFD(); + } + + if (nullptr != serializer.get()) + serializer.reset(nullptr); + + impl.release(); +} diff --git a/src/internal/storage_backend_serialized.hpp b/src/internal/storage_backend_serialized.hpp index c3406ac..dc3a861 100644 --- a/src/internal/storage_backend_serialized.hpp +++ b/src/internal/storage_backend_serialized.hpp @@ -21,8 +21,66 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include "policy.hpp" #include "storage_backend_flatbuffers.hpp" +#include "serializer.hpp" +#include +#include namespace ldp_serialized { -using StorageBackendSerialized = StorageBackendFlatbuffers; + +class StorageBackendSerialized +{ +public: + StorageBackendSerialized(); + ~StorageBackendSerialized(); + + bool init(const char *filename, bool verify = false); + bool initFromData(const uint8_t *serialized_data, size_t length, bool verify = false); + bool initFromXML(const char *config_name); + void release(); + + void printContent(bool xml_format = false) const + { impl.printContent(xml_format); } + + // Supported template parameters are: + // MatchItemOwn, MatchItemSend, MatchItemReceive + // and - only for Contexts - MatchItemAccess + template + ldp_xml_parser::DecisionItem getDecisionItemContextMandatory(const MatchItem &item) const + { return impl.getDecisionItemContextMandatory(item); } + template + ldp_xml_parser::DecisionItem getDecisionItemContextDefault(const MatchItem &item) const + { return impl.getDecisionItemContextDefault(item); } + template + ldp_xml_parser::DecisionItem getDecisionItemUser(uid_t uid, const MatchItem &item) const + { return impl.getDecisionItemUser(uid, item); } + template + ldp_xml_parser::DecisionItem getDecisionItemGroup(gid_t gid, const MatchItem &item) const + { return impl.getDecisionItemGroup(gid, item); } + + // This works with MatchItem set to MatchItemOwn, MatchItemSend or MatchItemReceive + // This is needed for filtering mapGroups. Check NaivePolicyChecker. + template + bool existsPolicyForGroup(gid_t gid) const + { return impl.existsPolicyForGroup(gid); } + +private: + typedef StorageBackendFlatbuffers Backend; + Backend impl; + + // Set max size of serialized file to prevent mmap with unexpected memory size. + // 1MB. Adjustable + static const size_t MAX_SFILE_SIZE{1024 * 1024}; + + int __fd{-1}; + uint8_t *__mem; + size_t __length{0}; + + std::unique_ptr serializer; + + void releaseMMap(); + void releaseFD(); +}; + } -- 2.7.4