diff options
author | Konrad Lipinski <k.lipinski2@partner.samsung.com> | 2019-01-09 13:33:23 +0100 |
---|---|---|
committer | Konrad Lipinski <k.lipinski2@partner.samsung.com> | 2019-01-11 11:50:29 +0100 |
commit | d169f1ce71d862062a247eb039c3ae11bc5bba3b (patch) | |
tree | 23e2387dd7905bd410b53fa14dcc839be1acb164 | |
parent | e4cd85b2c0eb6bbd063827e51e2b77d8278402de (diff) | |
download | security-manager-d169f1ce71d862062a247eb039c3ae11bc5bba3b.tar.gz security-manager-d169f1ce71d862062a247eb039c3ae11bc5bba3b.tar.bz2 security-manager-d169f1ce71d862062a247eb039c3ae11bc5bba3b.zip |
Apply db fallback is present and the db is an empty file
Change-Id: Idfa81003639c5452ae85e79257aa5425547d42ea
-rw-r--r-- | src/server/rules-loader/security-manager-rules-loader.cpp | 34 | ||||
-rw-r--r-- | test/test_privilege_db_migration.cpp | 9 |
2 files changed, 31 insertions, 12 deletions
diff --git a/src/server/rules-loader/security-manager-rules-loader.cpp b/src/server/rules-loader/security-manager-rules-loader.cpp index df5cc3f7..3a6dc323 100644 --- a/src/server/rules-loader/security-manager-rules-loader.cpp +++ b/src/server/rules-loader/security-manager-rules-loader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2018-2019 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. @@ -458,6 +458,19 @@ size_t sharedROPkgIndex = ~size_t(0); // temporary buffer for decimal author_id stringification (not \0-terminated) char authorBuf[std::numeric_limits<sqlite3_int64>::digits10 + 1]; +// fallback database path if not null +char const *cachedFallbackPath; +char const *getFallbackPath() { + if (likely(!cachedFallbackPath)) { + cachedFallbackPath = testLoader + ? TEST_PRIVILEGE_FALLBACK_DB_PATH + : tzplatform_mkpath3(TZ_SYS_RO_SHARE, "security-manager", ".security-manager.db"); + if (unlikely(!cachedFallbackPath)) + fail("tzplatform_mkpath(fallback) failed"); + } + return cachedFallbackPath; +} + // rule template code generated by sh$ policy/generate-rule-code policy/*.smack // included in anonymous namespace at this particular point to: @@ -526,9 +539,11 @@ inl bool fileEmpty(const char *filePath) { return !lstat(filePath, &st) && !st.st_size; } +enum class CheckFallback : bool { no, yes }; + // open dbPath, potentially migrating to newer version and applying schema, then checking integrity // return true iff successful -bool dbUp() { +bool dbUp(CheckFallback checkFallback) { if (unlikely(SQLITE_OK != sqlite3_open_v2(dbPath, &db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_NOMUTEX|SQLITE_OPEN_PRIVATECACHE, nullptr))) { toStderr("db open (%s) failed", dbPath); return false; @@ -583,10 +598,13 @@ bool dbUp() { return false; } } while (++version < dbVersion); + } else if (likely(underlying(checkFallback)) && likely(!access(getFallbackPath(), F_OK))) { + toStderr("empty db with fallback present - will apply the fallback"); + return false; } // apply schema - if (!dbExec(dbSchema)) { + if (unlikely(!dbExec(dbSchema))) { toStderr("db schema failed"); return false; } @@ -918,11 +936,7 @@ inl void overwriteDbFileWithFallback(size_t dbPathLen) { // retrieve fallback database file path // WARNING: dbPath memory has been made invalid (will restore later) due to tzplatform_mkpath* using a shared scratch buffer - char const *fallbackPath = testLoader - ? TEST_PRIVILEGE_FALLBACK_DB_PATH - : tzplatform_mkpath3(TZ_SYS_RO_SHARE, "security-manager", ".security-manager.db"); - if (unlikely(!fallbackPath)) - fail("tzplatform_mkpath(fallback) failed"); + char const *fallbackPath = getFallbackPath(); // open the fallback database regular file and get its size const int fallbackfd = open(fallbackPath, O_RDONLY); @@ -1035,7 +1049,7 @@ int main(int argc, char *argv[]) { // try to bring up the main database if fallback-only was not requested, otherwise remove tmpfs marker to avoid ambiguity bool mainDbUp = false; if (likely(!fallbackOnly)) - mainDbUp = dbUp(); + mainDbUp = dbUp(CheckFallback::yes); else if (unlikely(!unlinkIfExists(dbOkMarker))) fail("unlink(dbOkMarker) failed"); @@ -1049,7 +1063,7 @@ int main(int argc, char *argv[]) { overwriteDbFileWithFallback(dbPathLen); // try to bring up the restored database - if (unlikely(!dbUp())) + if (unlikely(!dbUp(CheckFallback::no))) fail("fallback db bringup failed"); // create the "database successfully recovered" marker file diff --git a/test/test_privilege_db_migration.cpp b/test/test_privilege_db_migration.cpp index b06b0fd8..e045eb4b 100644 --- a/test/test_privilege_db_migration.cpp +++ b/test/test_privilege_db_migration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2018-2019 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. @@ -71,7 +71,7 @@ struct PrivilegeV0DBFixture : PrivilegeDBFixture { PrivilegeV0DBFixture() : PrivilegeDBFixture(PRIVILEGE_DB_EXAMPLE_V0) {} }; struct PrivilegeEmptyDBFixture : PrivilegeDBFixture { - PrivilegeEmptyDBFixture() : PrivilegeDBFixture(PRIVILEGE_DB_EMPTY) {} + PrivilegeEmptyDBFixture() : PrivilegeDBFixture(PRIVILEGE_DB_EMPTY, {}) {} }; } //namespace @@ -107,6 +107,8 @@ BOOST_AUTO_TEST_CASE(T1570_fallback_canonicity) { }; go({}, Marker::fallback, false); go({}, Marker::fallback, true); + go(PRIVILEGE_DB_EMPTY, Marker::fallback, false); + go(PRIVILEGE_DB_EMPTY, Marker::fallback, true); go(PRIVILEGE_DB_CORRUPTED, Marker::fallback, false); go(PRIVILEGE_DB_CORRUPTED, Marker::fallback, true); go(PRIVILEGE_DB_WRONG_SCHEMA, Marker::standard, false); @@ -141,6 +143,9 @@ BOOST_AUTO_TEST_CASE(T1590_fallback_migration_failure) { go({}, {}, Marker::none); go({}, PRIVILEGE_DB_CORRUPTED, Marker::none); go({}, PRIVILEGE_DB_WRONG_SCHEMA, Marker::fallback); + // NOTE: PRIVILEGE_DB_EMPTY, {} is missing on purpose - in this case fallback is not attempted but db is schema-seeded instead + go(PRIVILEGE_DB_EMPTY, PRIVILEGE_DB_CORRUPTED, Marker::none); + go(PRIVILEGE_DB_EMPTY, PRIVILEGE_DB_WRONG_SCHEMA, Marker::fallback); go(PRIVILEGE_DB_CORRUPTED, {}, Marker::none); go(PRIVILEGE_DB_CORRUPTED, PRIVILEGE_DB_CORRUPTED, Marker::none); go(PRIVILEGE_DB_CORRUPTED, PRIVILEGE_DB_WRONG_SCHEMA, Marker::fallback); |