Sanitize privilege_db query storage
authorKonrad Lipinski <k.lipinski2@partner.samsung.com>
Thu, 12 Jul 2018 15:28:29 +0000 (17:28 +0200)
committerTomasz Swierczek <t.swierczek@samsung.com>
Wed, 8 Aug 2018 09:54:10 +0000 (11:54 +0200)
* replace PrivilegeDb::Queries map with a static array
* replace PrivilegeDb::m_commands vector with a fixed size array
* make module require C++ 14

Rationale:
* safety
* efficiency
* memory footprint

Change-Id: If69ab4525c293ae836c1d35af19b8cebf7bbff57

CMakeLists.txt
src/common/include/privilege_db.h
src/common/privilege_db.cpp

index dd6649c3fe5af8ef8c3721f86e166da0d3a0ab9b..a076ca5938d09598c6be7855b5371cfbedda1b24 100644 (file)
@@ -49,11 +49,11 @@ ADD_DEFINITIONS("-DPOLICY_DIR=\"${POLICY_DIR}\"")
 
 ############################# compiler flags ##################################
 
-SET(CMAKE_CXX_FLAGS_PROFILING  "-g -std=c++0x -O0 -pg -Wp,-U_FORTIFY_SOURCE")
-SET(CMAKE_CXX_FLAGS_DEBUG      "-g -std=c++0x -O0 -ggdb -Wp,-U_FORTIFY_SOURCE")
-SET(CMAKE_CXX_FLAGS_RELEASE    "-g -std=c++0x -O2")
-SET(CMAKE_CXX_FLAGS_CCOV       "-g -std=c++0x -O2 --coverage")
-SET(CMAKE_CXX_FLAGS_VALGRIND   "-ggdb -std=c++0x -O0 -fno-inline -Wp,-U_FORTIFY_SOURCE")
+SET(CMAKE_CXX_FLAGS_PROFILING  "-g -std=c++14 -O0 -pg -Wp,-U_FORTIFY_SOURCE")
+SET(CMAKE_CXX_FLAGS_DEBUG      "-g -std=c++14 -O0 -ggdb -Wp,-U_FORTIFY_SOURCE")
+SET(CMAKE_CXX_FLAGS_RELEASE    "-g -std=c++14 -O2")
+SET(CMAKE_CXX_FLAGS_CCOV       "-g -std=c++14 -O2 --coverage")
+SET(CMAKE_CXX_FLAGS_VALGRIND   "-ggdb -std=c++14 -O0 -fno-inline -Wp,-U_FORTIFY_SOURCE")
 
 # Force PIE
 SET(CMAKE_POSITION_INDEPENDENT_CODE "True")
index 357379b3d7c3e1f8e164c1b3a7f8ead74113bcad..010c605ad42b3f4a38b095b409b75f61fa46bb8e 100644 (file)
@@ -31,6 +31,7 @@
 
 #pragma once
 
+#include <array>
 #include <cstdio>
 #include <list>
 #include <utility>
@@ -46,7 +47,7 @@
 
 namespace SecurityManager {
 
-enum class StmtType {
+enum class StmtType : uint8_t {
     EAddApplication,
     ERemoveApplication,
     EPkgNameExists,
@@ -87,6 +88,7 @@ enum class StmtType {
     EGetLicenseForClientPrivilegeAndPkg,
     EIsUserPkgInstalled,
 };
+enum : uint8_t { StmtTypeCount = static_cast<uint8_t>(StmtType::EIsUserPkgInstalled) + 1 };
 
 // privilege, app_defined_privilege_type, license
 typedef std::tuple<std::string, int, std::string> AppDefinedPrivilege;
@@ -111,55 +113,13 @@ private:
     };
 
     SecurityManager::DB::SqlConnection mSqlConnection;
-    const std::map<StmtType, const char * const > Queries = {
-        { StmtType::EAddApplication, "INSERT INTO user_app_pkg_view (app_name, pkg_name, uid, version, author_name, is_hybrid)"
-                                    " VALUES (?, ?, ?, ?, ?, ?)" },
-        { StmtType::ERemoveApplication, "DELETE FROM user_app_pkg_view WHERE app_name=? AND uid=?" },
-        { StmtType::EPkgNameExists, "SELECT count(*) FROM pkg WHERE name=?" },
-        { StmtType::EAppNameExists, "SELECT count(*) FROM app WHERE name=?" },
-        { StmtType::EGetAppPkgName, "SELECT pkg_name FROM user_app_pkg_view WHERE app_name = ?" },
-        { StmtType::EGetAppVersion, "SELECT version FROM app WHERE name = ?" },
-        { StmtType::EGetPathSharedCount, "SELECT COUNT(*) FROM app_private_sharing_view WHERE path = ?"},
-        { StmtType::EGetTargetPathSharedCount, "SELECT COUNT(*) FROM app_private_sharing_view WHERE target_app_name = ? AND path = ?"},
-        { StmtType::EGetOwnerTargetSharedCount, "SELECT COUNT(*) FROM app_private_sharing_view WHERE owner_app_name = ? AND target_app_name = ?"},
-        { StmtType::EAddPrivatePathSharing, "INSERT INTO app_private_sharing_view(owner_app_name, target_app_name, path, path_label) VALUES(?, ?, ?, ?)"},
-        { StmtType::ERemovePrivatePathSharing, "DELETE FROM app_private_sharing_view WHERE owner_app_name = ? AND target_app_name = ? AND path = ?"},
-        { StmtType::EGetAllSharedPaths, "SELECT DISTINCT owner_app_name, path FROM app_private_sharing_view ORDER BY owner_app_name"},
-        { StmtType::EGetSharingForOwner, "SELECT target_app_name, path FROM app_private_sharing_view WHERE owner_app_name = ?"},
-        { StmtType::EGetSharingForTarget, "SELECT owner_app_name, path FROM app_private_sharing_view WHERE target_app_name = ?"},
-        { StmtType::ESquashSharing, "UPDATE app_private_sharing_view SET counter = 1 WHERE target_app_name = ? AND path = ?"},
-        { StmtType::EClearSharing, "DELETE FROM app_private_sharing;"},
-        { StmtType::EClearPrivatePaths, "DELETE FROM shared_path;"},
-        { StmtType::EGetUserApps, "SELECT app_name FROM user_app_pkg_view WHERE uid=?" },
-        { StmtType::EGetUserAppsFromPkg, "SELECT app_name FROM user_app_pkg_view WHERE uid = ? AND pkg_name = ?" },
-        { StmtType::EGetUserPkgs, "SELECT DISTINCT pkg_name FROM user_app_pkg_view WHERE uid=?" },
-        { StmtType::EGetAllPackages,  "SELECT DISTINCT pkg_name FROM user_app_pkg_view" },
-        { StmtType::EGetAppsInPkg, " SELECT app_name FROM user_app_pkg_view WHERE pkg_name = ?" },
-        { StmtType::EGetGroupsRelatedPrivileges, "SELECT DISTINCT group_name, privilege_name FROM privilege_group" },
-        { StmtType::EGetPkgAuthorId, "SELECT author_id FROM pkg WHERE name = ? AND author_id IS NOT NULL"},
-        { StmtType::EAuthorIdExists, "SELECT count(*) FROM author where author_id=?"},
-        { StmtType::EGetAuthorIdByName, "SELECT author_id FROM author WHERE name=?"},
-        { StmtType::ESetPackageSharedRO, "UPDATE pkg SET shared_ro=1 WHERE name=?"},
-        { StmtType::EIsPackageSharedRO, "SELECT shared_ro FROM pkg WHERE name=?"},
-        { StmtType::EIsPackageHybrid, "SELECT is_hybrid FROM pkg WHERE name=?"},
-        { StmtType::EGetPackagesInfo, "SELECT name, shared_ro, is_hybrid FROM pkg"},
-        { StmtType::EAddAppDefinedPrivilege, "INSERT INTO app_defined_privilege_view (app_name, uid, privilege, type, license) VALUES (?, ?, ?, ?, ?)"},
-        { StmtType::EAddClientPrivilege, "INSERT INTO client_license_view (app_name, uid, privilege, license) VALUES (?, ?, ?, ?)"},
-        { StmtType::ERemoveAppDefinedPrivileges, "DELETE FROM app_defined_privilege_view WHERE app_name = ? AND uid = ?"},
-        { StmtType::ERemoveClientPrivileges, "DELETE FROM client_license_view WHERE app_name = ? AND uid = ?"},
-        { StmtType::EGetAppDefinedPrivileges, "SELECT privilege, type, license FROM app_defined_privilege_view WHERE app_name = ? AND uid = ?"},
-        { StmtType::EGetAppPkgLicenseForAppDefinedPrivilege, "SELECT app_name, pkg_name, license FROM app_defined_privilege_view WHERE uid = ? AND privilege = ?"},
-        { StmtType::EGetLicenseForClientPrivilegeAndApp, "SELECT license FROM client_license_view WHERE app_name = ? AND uid = ? AND privilege = ? "},
-        { StmtType::EGetLicenseForClientPrivilegeAndPkg, "SELECT license FROM client_license_view WHERE pkg_name = ? AND uid = ? AND privilege = ? "},
-        { StmtType::EIsUserPkgInstalled, "SELECT count(*) FROM user_app_pkg_view WHERE pkg_name = ? AND uid = ?"},
-    };
 
     /**
      * Container for initialized DataCommands, prepared for binding.
      *
      * Destroyed before mSqlConnection.
      */
-    std::vector<DB::SqlConnection::DataCommandAutoPtr> m_commands;
+    std::array<DB::SqlConnection::DataCommandAutoPtr, StmtTypeCount> m_commands;
 
     /**
      * Fills empty m_commands map with sql commands prepared for binding.
index 73f5c91f635f3d0e75b557d3ee2dd3d231fb1fd4..9e36e97fcbf11477650077e467f868659c838a30 100644 (file)
 #include "filesystem.h"
 
 namespace SecurityManager {
+namespace {
+
+constexpr const char *g_queries[StmtTypeCount] = {
+    [int(StmtType::EAddApplication)] = "INSERT INTO user_app_pkg_view (app_name, pkg_name, uid, version, author_name, is_hybrid)"
+                                       " VALUES (?, ?, ?, ?, ?, ?)",
+    [int(StmtType::ERemoveApplication)] = "DELETE FROM user_app_pkg_view WHERE app_name=? AND uid=?",
+    [int(StmtType::EPkgNameExists)] = "SELECT count(*) FROM pkg WHERE name=?",
+    [int(StmtType::EAppNameExists)] = "SELECT count(*) FROM app WHERE name=?",
+    [int(StmtType::EGetAppPkgName)] = "SELECT pkg_name FROM user_app_pkg_view WHERE app_name = ?",
+    [int(StmtType::EGetAppVersion)] = "SELECT version FROM app WHERE name = ?",
+    [int(StmtType::EGetPathSharedCount)] = "SELECT COUNT(*) FROM app_private_sharing_view WHERE path = ?",
+    [int(StmtType::EGetTargetPathSharedCount)] = "SELECT COUNT(*) FROM app_private_sharing_view WHERE target_app_name = ? AND path = ?",
+    [int(StmtType::EGetOwnerTargetSharedCount)] = "SELECT COUNT(*) FROM app_private_sharing_view WHERE owner_app_name = ? AND target_app_name = ?",
+    [int(StmtType::EAddPrivatePathSharing)] = "INSERT INTO app_private_sharing_view(owner_app_name, target_app_name, path, path_label) VALUES(?, ?, ?, ?)",
+    [int(StmtType::ERemovePrivatePathSharing)] = "DELETE FROM app_private_sharing_view WHERE owner_app_name = ? AND target_app_name = ? AND path = ?",
+    [int(StmtType::EGetAllSharedPaths)] = "SELECT DISTINCT owner_app_name, path FROM app_private_sharing_view ORDER BY owner_app_name",
+    [int(StmtType::EGetSharingForOwner)] = "SELECT target_app_name, path FROM app_private_sharing_view WHERE owner_app_name = ?",
+    [int(StmtType::EGetSharingForTarget)] = "SELECT owner_app_name, path FROM app_private_sharing_view WHERE target_app_name = ?",
+    [int(StmtType::ESquashSharing)] = "UPDATE app_private_sharing_view SET counter = 1 WHERE target_app_name = ? AND path = ?",
+    [int(StmtType::EClearSharing)] = "DELETE FROM app_private_sharing;",
+    [int(StmtType::EClearPrivatePaths)] = "DELETE FROM shared_path;",
+    [int(StmtType::EGetUserApps)] = "SELECT app_name FROM user_app_pkg_view WHERE uid=?",
+    [int(StmtType::EGetUserAppsFromPkg)] = "SELECT app_name FROM user_app_pkg_view WHERE uid = ? AND pkg_name = ?",
+    [int(StmtType::EGetUserPkgs)] = "SELECT DISTINCT pkg_name FROM user_app_pkg_view WHERE uid=?",
+    [int(StmtType::EGetAllPackages)] =  "SELECT DISTINCT pkg_name FROM user_app_pkg_view",
+    [int(StmtType::EGetAppsInPkg)] = " SELECT app_name FROM user_app_pkg_view WHERE pkg_name = ?",
+    [int(StmtType::EGetGroupsRelatedPrivileges)] = "SELECT DISTINCT group_name, privilege_name FROM privilege_group",
+    [int(StmtType::EGetPkgAuthorId)] = "SELECT author_id FROM pkg WHERE name = ? AND author_id IS NOT NULL",
+    [int(StmtType::EAuthorIdExists)] = "SELECT count(*) FROM author where author_id=?",
+    [int(StmtType::EGetAuthorIdByName)] = "SELECT author_id FROM author WHERE name=?",
+    [int(StmtType::ESetPackageSharedRO)] = "UPDATE pkg SET shared_ro=1 WHERE name=?",
+    [int(StmtType::EIsPackageSharedRO)] = "SELECT shared_ro FROM pkg WHERE name=?",
+    [int(StmtType::EIsPackageHybrid)] = "SELECT is_hybrid FROM pkg WHERE name=?",
+    [int(StmtType::EGetPackagesInfo)] = "SELECT name, shared_ro, is_hybrid FROM pkg",
+    [int(StmtType::EAddAppDefinedPrivilege)] = "INSERT INTO app_defined_privilege_view (app_name, uid, privilege, type, license) VALUES (?, ?, ?, ?, ?)",
+    [int(StmtType::EAddClientPrivilege)] = "INSERT INTO client_license_view (app_name, uid, privilege, license) VALUES (?, ?, ?, ?)",
+    [int(StmtType::ERemoveAppDefinedPrivileges)] = "DELETE FROM app_defined_privilege_view WHERE app_name = ? AND uid = ?",
+    [int(StmtType::ERemoveClientPrivileges)] = "DELETE FROM client_license_view WHERE app_name = ? AND uid = ?",
+    [int(StmtType::EGetAppDefinedPrivileges)] = "SELECT privilege, type, license FROM app_defined_privilege_view WHERE app_name = ? AND uid = ?",
+    [int(StmtType::EGetAppPkgLicenseForAppDefinedPrivilege)] = "SELECT app_name, pkg_name, license FROM app_defined_privilege_view WHERE uid = ? AND privilege = ?",
+    [int(StmtType::EGetLicenseForClientPrivilegeAndApp)] = "SELECT license FROM client_license_view WHERE app_name = ? AND uid = ? AND privilege = ? ",
+    [int(StmtType::EGetLicenseForClientPrivilegeAndPkg)] = "SELECT license FROM client_license_view WHERE pkg_name = ? AND uid = ? AND privilege = ? ",
+    [int(StmtType::EIsUserPkgInstalled)] = "SELECT count(*) FROM user_app_pkg_view WHERE pkg_name = ? AND uid = ?",
+};
+
+template <class T, size_t S>
+constexpr bool allTrue(T (&array)[S]) {
+    for (auto &a : array) {
+        if (!a)
+            return false;
+    }
+    return true;
+}
+
+static_assert(allTrue(g_queries));
+
+template <StmtType i>
+constexpr const char *query = g_queries[size_t(i)];
+
+template <class T>
+constexpr void destroyAt(T *p) {
+    p->~T();
+}
+} //namespace
 
 /* Common code for handling SqlConnection exceptions */
 template <typename T>
@@ -94,8 +158,9 @@ PrivilegeDb::PrivilegeDb(const std::string &path)
 
 void PrivilegeDb::initDataCommands()
 {
-    for (auto &it : Queries) {
-        m_commands.push_back(mSqlConnection.PrepareDataCommand(it.second));
+    for (size_t i = 0; i < StmtTypeCount; i++) {
+        m_commands[i] = mSqlConnection.PrepareDataCommand(g_queries[i]);
+        Assert(m_commands[i]);
     }
 }
 
@@ -114,7 +179,7 @@ DB::SqlConnection::DataCommand* PrivilegeDb::StatementWrapper::operator->()
 
 PrivilegeDb::StatementWrapper PrivilegeDb::getStatement(StmtType queryType)
 {
-    return StatementWrapper(m_commands.at(static_cast<size_t>(queryType)));
+    return StatementWrapper(m_commands[int(queryType)]);
 }
 
 PrivilegeDb &PrivilegeDb::getInstance()
@@ -221,7 +286,7 @@ void PrivilegeDb::AddApplication(
 
         if (command->Step()) {
             LogDebug("Unexpected SQLITE_ROW answer to query: " <<
-                     Queries.at(StmtType::EAddApplication));
+                     query<StmtType::EAddApplication>);
         };
 
         LogDebug("Added appName: " << appName << ", pkgName: " << pkgName);
@@ -251,7 +316,7 @@ void PrivilegeDb::RemoveApplication(
 
         if (command->Step()) {
             LogDebug("Unexpected SQLITE_ROW answer to query: " <<
-                    Queries.at(StmtType::ERemoveApplication));
+                    query<StmtType::ERemoveApplication>);
         };
 
         LogDebug("Removed appName: " << appName);
@@ -600,7 +665,7 @@ void PrivilegeDb::AddAppDefinedPrivilege(const std::string &appName, uid_t uid,
 
         if (command->Step()) {
             LogDebug("Unexpected SQLITE_ROW answer to query: " <<
-                     Queries.at(StmtType::EAddAppDefinedPrivilege));
+                     query<StmtType::EAddAppDefinedPrivilege>);
         }
 
         LogDebug("Added privilege: " << std::get<0>(privilege) << " defined by: " << appName <<
@@ -627,7 +692,7 @@ void PrivilegeDb::AddClientPrivilege(const std::string &appName, uid_t uid, cons
 
         if (command->Step()) {
             LogDebug("Unexpected SQLITE_ROW answer to query: " <<
-                     Queries.at(StmtType::EAddClientPrivilege));
+                     query<StmtType::EAddClientPrivilege>);
         }
 
         LogDebug("Added privilege: " << privilege << " license: " << license <<
@@ -644,7 +709,7 @@ void PrivilegeDb::RemoveAppDefinedPrivileges(const std::string &appName, uid_t u
 
         if (command->Step()) {
             LogDebug("Unexpected SQLITE_ROW answer to query: " <<
-                     Queries.at(StmtType::ERemoveAppDefinedPrivileges));
+                     query<StmtType::ERemoveAppDefinedPrivileges>);
         };
 
         LogDebug("Removed privileges defined by: " << appName << " and user: " << uid);
@@ -660,7 +725,7 @@ void PrivilegeDb::RemoveClientPrivileges(const std::string &appName, uid_t uid)
 
         if (command->Step()) {
             LogDebug("Unexpected SQLITE_ROW answer to query: " <<
-                     Queries.at(StmtType::ERemoveClientPrivileges));
+                     query<StmtType::ERemoveClientPrivileges>);
         };
 
         LogDebug("Removed privileges used by: " << appName << " and user: " << uid);