summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonrad Lipinski <k.lipinski2@partner.samsung.com>2019-01-09 13:33:23 +0100
committerKonrad Lipinski <k.lipinski2@partner.samsung.com>2019-01-11 11:50:29 +0100
commitd169f1ce71d862062a247eb039c3ae11bc5bba3b (patch)
tree23e2387dd7905bd410b53fa14dcc839be1acb164
parente4cd85b2c0eb6bbd063827e51e2b77d8278402de (diff)
downloadsecurity-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.cpp34
-rw-r--r--test/test_privilege_db_migration.cpp9
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);