From: Krzysztof Jackiewicz Date: Mon, 27 Jan 2025 20:13:23 +0000 (+0100) Subject: Refactor smack labeling X-Git-Tag: accepted/tizen/unified/20250217.155039~12 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=85fdb881ffa993547da8049023fbfb27afb4513d;p=platform%2Fcore%2Fsecurity%2Fsecurity-manager.git Refactor smack labeling Change-Id: Ife4a8f6cbda9261bb3b7e778feda939200582671 --- diff --git a/src/common/smack-labels.cpp b/src/common/smack-labels.cpp index 34107487..0113ac35 100644 --- a/src/common/smack-labels.cpp +++ b/src/common/smack-labels.cpp @@ -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 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(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(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)