Refactor smack labeling 55/318855/26
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 27 Jan 2025 20:13:23 +0000 (21:13 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 13 Feb 2025 12:56:29 +0000 (13:56 +0100)
Change-Id: Ife4a8f6cbda9261bb3b7e778feda939200582671

src/common/smack-labels.cpp

index 3410748790e0606c0c8deef64067c90428ba3570..0113ac35f94c57362d41a0433f9e16598262b22b 100644 (file)
@@ -59,19 +59,6 @@ namespace SmackLabels {
 //! Smack label used for SECURITY_MANAGER_PATH_PUBLIC_RO paths (RO for all apps)
 const char *const LABEL_FOR_APP_PUBLIC_RO_PATH = "User::Home";
 
-typedef std::function<bool(const FTSENT*)> LabelDecisionFn;
-
-static bool labelAll(const FTSENT *ftsent __attribute__((unused)))
-{
-    return true;
-}
-
-static bool labelDirs(const FTSENT *ftsent)
-{
-    // label only directories
-    return (S_ISDIR(ftsent->fts_statp->st_mode));
-}
-
 static inline void pathSetSmack(const char *path, const Smack::Label &label,
         const char *xattr_name)
 {
@@ -82,48 +69,66 @@ static inline void pathSetSmack(const char *path, const Smack::Label &label,
     }
 }
 
-static void dirSetSmack(const std::string &path, const Smack::Label &label,
-        const char *xattr_name, LabelDecisionFn fn)
-{
-    char *const path_argv[] = {const_cast<char *>(path.c_str()), NULL};
-    FTSENT *ftsent;
+class PathSetup {
+public:
+    explicit PathSetup(bool transmute) : m_transmute(transmute) {}
+    void setup(const std::string &path)
+    {
+        // setting access label on everything in given directory and below
+        char *const path_argv[] = { const_cast<char*>(path.c_str()), NULL };
+        FTSENT *ftsent;
+
+        auto fts = makeUnique(fts_open(path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL), fts_close);
+        if (!fts) {
+            LogError("fts_open failed.");
+            ThrowMsg(SmackException::FileError, "fts_open failed.");
+        }
 
-    auto fts = makeUnique(fts_open(path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL), fts_close);
-    if (!fts) {
-        LogError("fts_open failed.");
-        ThrowMsg(SmackException::FileError, "fts_open failed.");
-    }
+        while ((ftsent = fts_read(fts.get())) != NULL) {
+            /* Check for error (FTS_ERR) or failed stat(2) (FTS_NS) */
+            if (ftsent->fts_info == FTS_ERR || ftsent->fts_info == FTS_NS) {
+                LogError("FTS_ERR error or failed stat(2) (FTS_NS)");
+                ThrowMsg(SmackException::FileError, "FTS_ERR error or failed stat(2) (FTS_NS)");
+            }
 
-    while ((ftsent = fts_read(fts.get())) != NULL) {
-        /* Check for error (FTS_ERR) or failed stat(2) (FTS_NS) */
-        if (ftsent->fts_info == FTS_ERR || ftsent->fts_info == FTS_NS) {
-            LogError("FTS_ERR error or failed stat(2) (FTS_NS)");
-            ThrowMsg(SmackException::FileError, "FTS_ERR error or failed stat(2) (FTS_NS)");
-        }
+            /* avoid to tag directories two times */
+            if (ftsent->fts_info == FTS_D)
+                continue;
 
-        /* avoid to tag directories two times */
-        if (ftsent->fts_info == FTS_D)
-            continue;
+            setupFile(ftsent);
+        }
 
-        if (fn(ftsent))
-            pathSetSmack(ftsent->fts_path, label, xattr_name);
+        /* If last call to fts_read() set errno, we need to return error. */
+        if ((errno != 0) && (ftsent == NULL))
+            LogAndThrowErrno(SmackException::FileError, "last fts_read");
     }
 
-    /* If last call to fts_read() set errno, we need to return error. */
-    if ((errno != 0) && (ftsent == NULL))
-        LogAndThrowErrno(SmackException::FileError, "last fts_read");
-}
+    virtual ~PathSetup() = default;
 
-static void labelDir(const std::string &path, const Smack::Label &label,
-        bool set_transmutable)
-{
-    // setting access label on everything in given directory and below
-    dirSetSmack(path, label, XATTR_NAME_SMACK, labelAll);
+protected:
+    virtual void setupFile(FTSENT *ftsent) = 0;
 
-    // setting transmute on dirs
-    if (set_transmutable)
-        dirSetSmack(path, "TRUE", XATTR_NAME_SMACKTRANSMUTE, labelDirs);
-}
+    bool m_transmute;
+};
+
+class SmackSetup: public PathSetup {
+public:
+    SmackSetup(const std::string label, bool transmute) :
+            PathSetup(transmute), m_label(std::move(label))
+    {
+    }
+
+protected:
+    void setupFile(FTSENT *ftsent) override
+    {
+        pathSetSmack(ftsent->fts_path, m_label, XATTR_NAME_SMACK);
+        if (m_transmute && S_ISDIR(ftsent->fts_statp->st_mode))
+            pathSetSmack(ftsent->fts_path, "TRUE", XATTR_NAME_SMACKTRANSMUTE);
+    }
+
+private:
+    std::string m_label;
+};
 
 void setupPath(
         const std::string &pkgName,
@@ -162,10 +167,10 @@ void setupPath(
         LogError("Path type not known.");
         Throw(SmackException::InvalidPathType);
     }
-    if (follow_symlink) {
-        labelDir(realPath(path), label, label_transmute);
-    }
-    return labelDir(path, label, label_transmute);
+    SmackSetup smack(label, label_transmute);
+    if (follow_symlink)
+        smack.setup(realPath(path));
+    smack.setup(path);
 }
 
 void setupPkgBasePath(const std::string &basePath)