Implement a mechanism for permissible file repair
authorFilip Skrzeczkowski <f.skrzeczkow@samsung.com>
Thu, 28 Sep 2023 11:19:50 +0000 (13:19 +0200)
committerTomasz Swierczek <t.swierczek@samsung.com>
Wed, 29 Nov 2023 10:07:29 +0000 (11:07 +0100)
Permissible files that have been marked as invalid due to their hash
not matching can now be repaired by fetching the relevant data directly
form PrivilegeDb. This works for both the service and the client library.
As the client lacks the privileges to do it on their own, in that case
a request is sent to the Security Manager daemon.

Change-Id: I43fee3d39c015a7fbba0e674c29c904ac26e91bf

src/client/client-label-monitor.cpp
src/common/include/permissible-set.h
src/common/include/protocols.h
src/common/include/service_impl.h
src/common/permissible-set.cpp
src/common/protocols.cpp
src/common/service_impl.cpp
src/server/service/include/service.h
src/server/service/service.cpp

index 1958376..7050cf2 100644 (file)
@@ -44,6 +44,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#include <client-request.h>
 #include <config.h>
 #include <dpl/log/log.h>
 #include <dpl/errno_string.h>
@@ -51,6 +52,7 @@
 #include <permissible-set.h>
 #include <protocols.h>
 #include <smack-labels.h>
+#include <tzplatform-config.h>
 #include <utils.h>
 
 struct app_labels_monitor {
@@ -58,24 +60,93 @@ struct app_labels_monitor {
     int global_labels_file_watch;
     int user_labels_file_watch;
     bool fresh;
+    uid_t uid;
     std::string user_label_file_path;
     std::string global_label_file_path;
     app_labels_monitor() : inotify(-1), global_labels_file_watch(-1), user_labels_file_watch(-1),
-                           fresh(true) {}
+                           fresh(true), uid(-1) {}
 };
 
-static lib_retcode apply_relabel_list(const std::string &global_label_file,
-        const std::string &user_label_file)
+static lib_retcode inotify_add_watch_full(int fd, const char* pathname, uint32_t mask, int *wd)
+{
+    int inotify_fd = inotify_add_watch(fd, pathname, mask);
+    if (inotify_fd == -1) {
+        LogErrno("Inotify watch on file " << pathname);
+        return SECURITY_MANAGER_ERROR_WATCH_ADD_TO_FILE_FAILED;
+    }
+    *wd = inotify_fd;
+    return SECURITY_MANAGER_SUCCESS;
+}
+
+static lib_retcode monitor_repair_permissible_file(uid_t uid, const std::string &label_file_path, app_install_type install_type)
+{
+    LogWarning("Permissible file may be corrupted, sending request to repair: " << label_file_path);
+
+    ClientRequest request(SecurityModuleCall::REPAIR_PERMISSIBLE_FILE);
+    if (request.send(uid, install_type).failed()) {
+        return SECURITY_MANAGER_ERROR_SOCKET;
+    }
+    if (request.getStatus() != SECURITY_MANAGER_SUCCESS) {
+        return SECURITY_MANAGER_ERROR_FILE_INTEGRITY;
+    }
+
+    return SECURITY_MANAGER_SUCCESS;
+}
+
+static lib_retcode initialize_inotify(app_labels_monitor *monitor)
+{
+    lib_retcode ret_lib;
+    int ret = inotify_init();
+    if (ret == -1) {
+        LogErrno("Inotify init");
+        return SECURITY_MANAGER_ERROR_WATCH_ADD_TO_FILE_FAILED;
+    }
+    monitor->inotify = ret;
+    ret_lib = inotify_add_watch_full(monitor->inotify, monitor->global_label_file_path.c_str(),
+            IN_CLOSE_WRITE | IN_DELETE_SELF, &(monitor->global_labels_file_watch));
+    if (ret_lib != SECURITY_MANAGER_SUCCESS) {
+        security_manager_app_labels_monitor_finish(monitor);
+        return ret_lib;
+    }
+    ret_lib = inotify_add_watch_full(monitor->inotify, monitor->user_label_file_path.c_str(),
+            IN_CLOSE_WRITE | IN_DELETE_SELF, &(monitor->user_labels_file_watch));
+    if (ret_lib != SECURITY_MANAGER_SUCCESS) {
+        security_manager_app_labels_monitor_finish(monitor);
+        return ret_lib;
+    }
+
+    return SECURITY_MANAGER_SUCCESS;
+}
+
+static void readPermissibleFile(std::vector<std::string> &appLabels, const std::string &filePath, app_install_type installType, uid_t uid)
+{
+    try {
+        PermissibleSet::readLabelsFromPermissibleFile(filePath, appLabels);
+    } catch(PermissibleSet::PermissibleSetException::FileIntegrityError &e) {
+        lib_retcode ret = monitor_repair_permissible_file(uid, filePath, installType);
+        if (ret != SECURITY_MANAGER_SUCCESS) {
+            LogError("Repair failed: " << ret);
+            throw;
+        }
+        PermissibleSet::readLabelsFromPermissibleFile(filePath, appLabels);
+    }
+}
+
+static lib_retcode apply_relabel_list(app_labels_monitor *monitor)
 {
     std::vector<std::string> appLabels;
 
     try {
-        PermissibleSet::readLabelsFromPermissibleFile(global_label_file, appLabels);
-        PermissibleSet::readLabelsFromPermissibleFile(user_label_file, appLabels);
-        std::vector<const char*> temp;
+        readPermissibleFile(appLabels, monitor->global_label_file_path,
+            SM_APP_INSTALL_GLOBAL, TizenPlatformConfig::getUid(TZ_SYS_GLOBALAPP_USER));
+        readPermissibleFile(appLabels, monitor->user_label_file_path,
+            SM_APP_INSTALL_LOCAL, monitor->uid);
+
+        std::vector<const char *> temp;
 
         std::transform(appLabels.begin(), appLabels.end(), std::back_inserter(temp),
-                [] (std::string &label) {return label.c_str();});
+                        [](std::string &label)
+                        { return label.c_str(); });
 
         if (smack_set_relabel_self(temp.data(), temp.size()) != 0) {
             LogError("smack_set_relabel_self failed");
@@ -94,17 +165,6 @@ static lib_retcode apply_relabel_list(const std::string &global_label_file,
     return SECURITY_MANAGER_SUCCESS;
 }
 
-static lib_retcode inotify_add_watch_full(int fd, const char* pathname, uint32_t mask, int *wd)
-{
-    int inotify_fd = inotify_add_watch(fd, pathname, mask);
-    if (inotify_fd == -1) {
-        LogErrno("Inotify watch on file " << pathname);
-        return SECURITY_MANAGER_ERROR_WATCH_ADD_TO_FILE_FAILED;
-    }
-    *wd = inotify_fd;
-    return SECURITY_MANAGER_SUCCESS;
-}
-
 SECURITY_MANAGER_API
 int security_manager_app_labels_monitor_init(app_labels_monitor **monitor)
 {
@@ -114,8 +174,6 @@ int security_manager_app_labels_monitor_init(app_labels_monitor **monitor)
             LogWarning("Error input param \"monitor\"");
             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
         }
-        int ret;
-        lib_retcode ret_lib;
 
         *monitor = nullptr;
 
@@ -131,25 +189,15 @@ int security_manager_app_labels_monitor_init(app_labels_monitor **monitor)
         const std::string userFile =
             PermissibleSet::getPermissibleFileLocation(uid, SM_APP_INSTALL_LOCAL);
 
-
-        ret = inotify_init();
-        if (ret == -1) {
-            LogErrno("Inotify init");
-            return SECURITY_MANAGER_ERROR_WATCH_ADD_TO_FILE_FAILED;
-        }
-        monitorPtr.get()->inotify = ret;
-        ret_lib = inotify_add_watch_full(monitorPtr->inotify, globalFile.c_str(),
-                IN_CLOSE_WRITE, &(monitorPtr->global_labels_file_watch));
-        if (ret_lib != SECURITY_MANAGER_SUCCESS) {
-            return ret_lib;
-        }
-        ret_lib = inotify_add_watch_full(monitorPtr->inotify, userFile.c_str(),
-                IN_CLOSE_WRITE, &(monitorPtr->user_labels_file_watch));
-        if (ret_lib != SECURITY_MANAGER_SUCCESS) {
-            return ret_lib;
-        }
+        monitorPtr->uid = uid;
         monitorPtr->user_label_file_path = userFile;
         monitorPtr->global_label_file_path = globalFile;
+
+        lib_retcode lib_ret = initialize_inotify(monitorPtr.get());
+        if (lib_ret != SECURITY_MANAGER_SUCCESS) {
+            LogErrno("Error during initializing inotify");
+            return lib_ret;
+        }
         *monitor = monitorPtr.release();
         return SECURITY_MANAGER_SUCCESS;
     });
@@ -171,14 +219,17 @@ void security_manager_app_labels_monitor_finish(app_labels_monitor *monitor)
                 if (ret == -1) {
                     LogErrno("Inotify watch removal on file " << APPS_LABELS_FILE);
                 }
+                monitorPtr->global_labels_file_watch = -1;
             }
             if (monitorPtr->user_labels_file_watch != -1) {
                 int ret = inotify_rm_watch(monitorPtr->inotify, monitorPtr->user_labels_file_watch);
                 if (ret == -1) {
                     LogErrno("Inotify watch removal on file " << monitor->user_label_file_path);
                 }
+                monitorPtr->user_labels_file_watch = -1;
             }
             close(monitorPtr->inotify);
+            monitorPtr->inotify = -1;
         }
         return 0;
     });
@@ -229,8 +280,7 @@ int security_manager_app_labels_monitor_process(app_labels_monitor *monitor)
 
         if (monitor->fresh) {
             monitor->fresh = false;
-            return apply_relabel_list(monitor->global_label_file_path,
-                   monitor->user_label_file_path);
+            return apply_relabel_list(monitor);
         }
 
         int avail;
@@ -260,12 +310,34 @@ int security_manager_app_labels_monitor_process(app_labels_monitor *monitor)
                 ((event.wd == monitor->global_labels_file_watch) ||
                  (event.wd == monitor->user_labels_file_watch))
                ){
-                lib_retcode r = apply_relabel_list(monitor->global_label_file_path,
-                                                   monitor->user_label_file_path);
+                lib_retcode r = apply_relabel_list(monitor);
                 if (r != SECURITY_MANAGER_SUCCESS)
                     return r;
                 break;
             }
+            if ((event.mask & IN_DELETE_SELF) &&
+                ((event.wd == monitor->global_labels_file_watch) ||
+                 (event.wd == monitor->user_labels_file_watch))
+               ){
+                if (event.wd == monitor->global_labels_file_watch) {
+                    lib_retcode r = inotify_add_watch_full(monitor->inotify, monitor->global_label_file_path.c_str(),
+                                    IN_CLOSE_WRITE | IN_DELETE_SELF, &(monitor->global_labels_file_watch));
+                    if (r != SECURITY_MANAGER_SUCCESS) {
+                        monitor->global_labels_file_watch = -1;
+                        return r;
+                    }
+
+                }
+                if (event.wd == monitor->user_labels_file_watch) {
+                    lib_retcode r = inotify_add_watch_full(monitor->inotify, monitor->user_label_file_path.c_str(),
+                                    IN_CLOSE_WRITE | IN_DELETE_SELF, &(monitor->user_labels_file_watch));
+                    if (r != SECURITY_MANAGER_SUCCESS) {
+                        monitor->user_labels_file_watch = -1;
+                        return r;
+                    }
+                }
+                break;
+            }
         }
         return SECURITY_MANAGER_SUCCESS;
     });
index aaa6d5b..88588cb 100644 (file)
@@ -34,6 +34,7 @@
 #include <vector>
 
 #include <dpl/exception.h>
+#include <privilege_db.h>
 #include <security-manager-types.h>
 
 namespace SecurityManager {
@@ -109,6 +110,16 @@ void updatePermissibleFile(uid_t uid, int installationType,
  */
 void readLabelsFromPermissibleFile(const std::string &nameFile, std::vector<std::string> &appLabels);
 
+/**
+ * Attempt to repair a possibly corrupted permissible file by reading directly from PrivilegeDb
+ * @throws FileOpenError
+ * @throws FileWriteError
+ *
+ * @param[in] uid user id
+ * @param[in] installationType type of installation (global or local)
+ */
+void repairPermissibleFile(uid_t uid, int installationType, PrivilegeDb &privilegeDb);
+
 void initializeUserPermissibleFile(uid_t uid);
 
 void removeUserPermissibleFile(uid_t uid);
index c421833..99604dc 100644 (file)
@@ -145,6 +145,7 @@ enum class SecurityModuleCall
     GET_APP_MANIFEST_POLICY,
     GET_PROCESS_LABEL,
     PREPARE_APP,
+    REPAIR_PERMISSIBLE_FILE,
     NOOP = 0x90,
 };
 
index 0cb1e7c..687f3cb 100644 (file)
@@ -390,6 +390,16 @@ public:
             Smack::Label &label, std::string &pkgName, PrepareAppFlags &prepareAppFlags,
             std::vector<gid_t> &forbiddenGroups, std::vector<gid_t> &allowedGroups, std::vector<bool> &privPathsStatusVector);
 
+    /**
+     * Repair the possibly corrupted permissible file specified by input arguments
+     *
+     * @param[in] uid user id
+     * @param[in] installationType type of installation (global or local)
+     *
+     * @return API return code, as defined in protocols.h
+     */
+    int repairPermissibleFileForClient(uid_t uid, int installationType);
+
 private:
     int appInstallInitialChecks(const Credentials &creds,
                                 app_inst_req &req);
@@ -421,6 +431,10 @@ private:
 
     int appUninstallSmackRules(app_inst_req &req, UninstallHelper &uh);
 
+    void tryUpdatePermissibleFile(uid_t uid, int installationType,
+                                    const std::vector<std::string> &newLabels,
+                                    const std::vector<std::string> &oldLabels);
+
     bool authenticate(const Credentials &creds, const std::string &privilege);
 
     bool authCheck(const Credentials &creds,
index b8e826e..8fb4a99 100644 (file)
 namespace SecurityManager {
 namespace PermissibleSet {
 
-static const char*  hashMarker = "-SHA-1";
-static const int    hashMarkerLength = strlen(hashMarker);
-static const int    hashLength = 40;
+static const char*   tempFileName = "temp";
+static const char*   hashMarker = "-SHA-1";
+static const int     hashMarkerLength = strlen(hashMarker);
+static constexpr int hashLength = 40;
+
+class ScopedTemporaryFile
+{
+public:
+    const std::string path = std::string(LOCAL_STATE_INSTALL_DIR) + "/" + tempFileName;
+
+    ~ScopedTemporaryFile()
+    {
+        if (unlink(path.c_str()) != 0 && errno != ENOENT)
+            LogErrno("remove temporary permissible file");
+    }
+};
 
 template <typename T>
 static inline int getFd(T &fstream)
@@ -116,6 +129,24 @@ std::string calculateHash(const std::string& content)
     return ss.str();
 }
 
+static void writeToPermissibleFile(const std::string &nameFile, std::ofstream &fstream, const std::stringstream &ss)
+{
+    auto content = ss.str();
+    auto hash = calculateHash(content);
+
+    fstream << hashMarker << " " << hash << '\n' << content;
+
+    if (fstream.bad()) {
+        LogAndThrowErrno(PermissibleSetException::FileWriteError, "write to file " << nameFile);
+    }
+    if (fstream.flush().fail()) {
+        LogAndThrowErrno(PermissibleSetException::FileWriteError, "fflush " << nameFile);
+    }
+    if (fsync(getFd(fstream)) == -1) {
+        LogAndThrowErrno(PermissibleSetException::FileWriteError, "fsync " << nameFile);
+    }
+}
+
 void verifyFileIntegrity(const std::string &nameFile, std::ifstream &fstream)
 {
     auto fileSize = std::filesystem::file_size(nameFile);
@@ -205,27 +236,15 @@ void updatePermissibleFile(uid_t uid, int installationType,
             labelsForUser.push_back(l);
     }
 
-    std::ofstream fstream;
-    openAndLockNameFile(nameFile, fstream);
-    markPermissibleFileValid(getFd(fstream), nameFile, false);
-
     std::stringstream ss;
     for (auto &label : labelsForUser) {
         ss << label << '\n';
     }
 
-    auto content = ss.str();
-    auto hash = calculateHash(content);
-
-    fstream << hashMarker << "\n" << hash << '\n' << content;
-
-    if (fstream.bad())
-            LogAndThrowErrno(PermissibleSetException::PermissibleSetException::FileWriteError,
-                    "write to file " << nameFile);
-    if (fstream.flush().fail())
-        LogAndThrowErrno(PermissibleSetException::FileWriteError, "fflush " << nameFile);
-    if (fsync(getFd(fstream)) == -1)
-        LogAndThrowErrno(PermissibleSetException::FileWriteError, "fsync " << nameFile);
+    std::ofstream fstream;
+    openAndLockNameFile(nameFile, fstream);
+    markPermissibleFileValid(getFd(fstream), nameFile, false);
+    writeToPermissibleFile(nameFile, fstream, ss);
     markPermissibleFileValid(getFd(fstream), nameFile, true);
 }
 
@@ -244,6 +263,34 @@ void readLabelsFromPermissibleFile(const std::string &nameFile, std::vector<std:
         LogAndThrowErrno(PermissibleSetException::FileReadError, "reading file " << nameFile);
 }
 
+void repairPermissibleFile(uid_t uid, int installationType, PrivilegeDb &privilegeDb)
+{
+    std::string nameFile = getPermissibleFileLocation(uid, installationType);
+    std::vector<std::string> appNames;
+    privilegeDb.GetUserApps(uid, appNames);
+
+    std::stringstream ss;
+    for (auto &appName : appNames) {
+        std::string pkgName;
+        privilegeDb.GetAppPkgName(appName, pkgName);
+        bool isPkgHybrid = privilegeDb.IsPackageHybrid(pkgName);
+
+        ss << SmackLabels::generateProcessLabel(appName, pkgName, isPkgHybrid) << '\n';
+    }
+    {
+        ScopedTemporaryFile temporaryFile;
+
+        std::ofstream fstream(temporaryFile.path);
+        if (!fstream.is_open())
+            LogAndThrowErrno(PermissibleSetException::FileOpenError, "open file " << nameFile);
+
+        writeToPermissibleFile(temporaryFile.path, fstream, ss);
+        if (rename(temporaryFile.path.c_str(), nameFile.c_str()) != 0)
+            ThrowErrno(PermissibleSetException::FileWriteError,
+            "move temporary file");
+    }
+}
+
 void initializeUserPermissibleFile(uid_t uid)
 {
     std::string nameFile = getPermissibleFileLocation(uid, SM_APP_INSTALL_LOCAL);
index b7a8e77..5aabc56 100644 (file)
@@ -60,6 +60,7 @@ const char * SecurityModuleCallToString(SecurityModuleCall call_num) {
         SM_CODE_DESCRIBE(SecurityModuleCall::GET_APP_MANIFEST_POLICY);
         SM_CODE_DESCRIBE(SecurityModuleCall::GET_PROCESS_LABEL);
         SM_CODE_DESCRIBE(SecurityModuleCall::PREPARE_APP);
+        SM_CODE_DESCRIBE(SecurityModuleCall::REPAIR_PERMISSIBLE_FILE);
         SM_CODE_DESCRIBE(SecurityModuleCall::NOOP);
         default: return "Code not defined";
     }
index 76a5602..fd612f4 100644 (file)
@@ -554,6 +554,19 @@ int ServiceImpl::appInstallSmackRules(app_inst_req &req, InstallHelper &ih)
     return SECURITY_MANAGER_SUCCESS;
 }
 
+void ServiceImpl::tryUpdatePermissibleFile(uid_t uid, int installationType,
+                                    const std::vector<std::string> &newLabels,
+                                    const std::vector<std::string> &oldLabels)
+{
+    try {
+        PermissibleSet::updatePermissibleFile(uid, installationType, newLabels, oldLabels);
+    } catch (const PermissibleSet::PermissibleSetException::FileIntegrityError &e) {
+        LogWarning("Permissible file may be corrupted, attempting repair: " << e.DumpToString());
+        PermissibleSet::repairPermissibleFile(uid, installationType, m_privilegeDb);
+        PermissibleSet::updatePermissibleFile(uid, installationType, newLabels, oldLabels);
+    }
+}
+
 int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &req)
 {
     int ret;
@@ -604,7 +617,7 @@ int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &req)
         getPkgLabels(req.pkgName, newLabels);
 
         // update permissible set
-        PermissibleSet::updatePermissibleFile(req.uid, req.installationType, newLabels, oldLabels);
+        tryUpdatePermissibleFile(req.uid, req.installationType, newLabels, oldLabels);
 
         // label paths
         ret = labelPaths(req.pkgPaths,
@@ -630,6 +643,9 @@ int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &req)
     } catch (const CynaraException::Base &e) {
         LogError("Error while setting Cynara rules for application: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+    } catch (const PermissibleSet::PermissibleSetException::FileIntegrityError &e) {
+        LogError("Error while updating permissible file - integrity error has been detected but it could not be fixed: " << e.DumpToString());
+        return SECURITY_MANAGER_ERROR_FILE_INTEGRITY;
     } catch (const PermissibleSet::PermissibleSetException::Base &e) {
         LogError("Error while updating permissible file: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
@@ -718,7 +734,7 @@ int ServiceImpl::appUpdate(const Credentials &creds, app_inst_req &req)
         getPkgLabels(req.pkgName, newLabels);
 
         // update permissible set
-        PermissibleSet::updatePermissibleFile(req.uid, req.installationType, newLabels, oldLabels);
+        tryUpdatePermissibleFile(req.uid, req.installationType, newLabels, oldLabels);
 
         // label paths
         ret = labelPaths(req.pkgPaths,
@@ -744,6 +760,9 @@ int ServiceImpl::appUpdate(const Credentials &creds, app_inst_req &req)
     } catch (const CynaraException::Base &e) {
         LogError("Error while setting Cynara rules for application: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+    } catch (const PermissibleSet::PermissibleSetException::FileIntegrityError &e) {
+        LogError("Error while updating permissible file - integrity error has been detected but it could not be fixed: " << e.DumpToString());
+        return SECURITY_MANAGER_ERROR_FILE_INTEGRITY;
     } catch (const PermissibleSet::PermissibleSetException::Base &e) {
         LogError("Error while updating permissible file: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
@@ -976,7 +995,7 @@ int ServiceImpl::appUninstall(const Credentials &creds, app_inst_req &req)
             getPkgLabels(req.pkgName, newLabels);
 
         // update permissible set
-        PermissibleSet::updatePermissibleFile(req.uid, req.installationType, newLabels, oldLabels);
+        tryUpdatePermissibleFile(req.uid, req.installationType, newLabels, oldLabels);
 
         // remove and merge Smack rules for apps and pkg
         return appUninstallSmackRules(req, uh);
@@ -986,6 +1005,9 @@ int ServiceImpl::appUninstall(const Credentials &creds, app_inst_req &req)
     } catch (const PrivilegeDb::Exception::Base &e) {
         LogError("Error while removing application info from database: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+    } catch (const PermissibleSet::PermissibleSetException::FileIntegrityError &e) {
+        LogError("Error while updating permissible file - integrity error has been detected but it could not be fixed: " << e.DumpToString());
+        return SECURITY_MANAGER_ERROR_FILE_INTEGRITY;
     } catch (const PermissibleSet::PermissibleSetException::Base &e) {
         LogError("Error while updating permissible file: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
@@ -2315,4 +2337,20 @@ int ServiceImpl::prepareApp(const Credentials &creds, const std::string &appName
     }
 }
 
+int ServiceImpl::repairPermissibleFileForClient(uid_t uid, int installationType)
+{
+    try {
+        PermissibleSet::repairPermissibleFile(uid, installationType, m_privilegeDb);
+    }
+    catch (PermissibleSet::PermissibleSetException::Base &e){
+        LogErrno("error while repairing the permissible file: " << e.DumpToString());
+        return SECURITY_MANAGER_ERROR_FILE_INTEGRITY;
+    } catch (...){
+        LogErrno("other error during permissible file repair ");
+        return SECURITY_MANAGER_ERROR_UNKNOWN;
+    }
+
+    return SECURITY_MANAGER_SUCCESS;
+}
+
 } /* namespace SecurityManager */
index e433f29..86bb407 100644 (file)
@@ -250,6 +250,13 @@ private:
      * @param creds  credentials of the requesting process
      */
     void prepareApp(MessageBuffer &buffer, const Credentials &creds);
+
+    /**
+     * Repair the requested Smack permissible file by fetching data from PrivilegeDb
+     *
+     * @param buffer Input/output message buffer
+     */
+    void processRepairPermissibleFile(MessageBuffer &buffer);
 };
 
 } // namespace SecurityManager
index c12dd6a..4545de2 100644 (file)
@@ -160,6 +160,9 @@ void Service::processEvent(Event &&msg)
             case SecurityModuleCall::PREPARE_APP:
                 prepareApp(msg.buffer, msg.creds);
                 break;
+            case SecurityModuleCall::REPAIR_PERMISSIBLE_FILE:
+                processRepairPermissibleFile(msg.buffer);
+                break;
             default:
                 LogError("Invalid call: " << call_type_int);
                 Throw(ServiceException::InvalidAction);
@@ -514,4 +517,17 @@ void Service::prepareApp(MessageBuffer &buffer, const Credentials &creds)
         Serialization::Serialize(buffer, forbiddenGroups, allowedGroups, privPathsStatusVector, label, pkgName, prepareAppFlags);
 }
 
+void Service::processRepairPermissibleFile(MessageBuffer &buffer)
+{
+    uid_t uid;
+    int installationType;
+
+    Deserialization::Deserialize(buffer, uid, installationType);
+
+    int ret = m_serviceImpl.repairPermissibleFileForClient(uid, installationType);
+
+    buffer.ModeStreaming();
+    Serialization::Serialize(buffer, ret);
+}
+
 } // namespace SecurityManager