[fix] sessiond: Correct handling of the TRANSMUTE attribute 75/280475/6
authorAdam Michalski <a.michalski2@partner.samsung.com>
Tue, 30 Aug 2022 12:39:13 +0000 (14:39 +0200)
committerAdam Michalski <a.michalski2@partner.samsung.com>
Thu, 1 Sep 2022 11:04:00 +0000 (13:04 +0200)
Due to its different nature (being inheritable) it wasn't handled
properly in some cases (e.g., for subdirectories that had it set
to false whose parent was set to true).

Also significantly simplified the logic by adding a helper function
and refactoring the `copy_smack_attributes` routine.

Change-Id: I3ee146056682e2380932fdd9052efe25e5d7f735
Co-author: Michal Bloch <m.bloch@samsung.com>

CMakeLists.txt
sessiond/src/fs_helpers.cpp
sessiond/src/fs_helpers.h

index 79592d3..d03fff9 100644 (file)
@@ -6,8 +6,8 @@ project(sessiond LANGUAGES C CXX)
 set(CMAKE_SHARED_LIBRARY_PREFIX "")
 
 # Needed for ASLR to work
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fPIE -Wno-error=shadow -Werror=missing-field-initializers")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fPIE -Wno-error=shadow -Werror=missing-field-initializers")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fPIE -Wno-error=shadow -Werror=missing-field-initializers -fconcepts")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fPIE -Wno-error=shadow -Werror=missing-field-initializers -fconcepts")
 set(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie")
 
 add_subdirectory(common)
index 35946c4..822bb7f 100644 (file)
@@ -99,6 +99,30 @@ std::string fs_helpers::get_smack_label(std::string_view src_path, smack_label_t
        return out_str;
 }
 
+int fs_helpers::copy_label(auto label, auto dest_path, auto type)
+{
+       if (type != SMACK_LABEL_TRANSMUTE)
+               return smack_lsetlabel(dest_path.data(), label.c_str(), type);
+
+       /* Setting TRANSMUTE attribute needs special attention:
+        * the only correct values are: NULL, "", "0" or "1" */
+       if (label == "TRUE")
+               return smack_lsetlabel(dest_path.data(), "1", type);
+
+       /* N.B. This is a bit tricky. Since TRANSMUTE attribute is inheritable,
+        * it is possible that it was set to TRUE while copying the files from
+        * /etc/skel, but originally it wasn't there in the source directory for
+        * some subdirectories/files. Therefore it must be removed explicitly. */
+       int ret = smack_lsetlabel(dest_path.data(), "0", type);
+       if (ret == -1 && errno == ENODATA) {
+               /* We tried to drop the label, but it already didn't exist,
+                * so the "error" is expected and not a problem. */
+               return 0;
+       }
+
+       return ret;
+}
+
 void fs_helpers::copy_smack_attributes(std::string_view src_path, std::string_view dest_path)
 {
        static const enum smack_label_type label_types[] = {
@@ -108,18 +132,8 @@ void fs_helpers::copy_smack_attributes(std::string_view src_path, std::string_vi
 
        for (const auto type : label_types) {
                auto label = get_smack_label(src_path, type);
-               int ret = 0;
-
-               if (type == SMACK_LABEL_TRANSMUTE) {
-                       // N.B. Setting TRANSMUTE attribute needs special attention:
-                       // the only correct values are: NULL, "", "0" or "1".
-                       if (label == "TRUE")
-                               ret = smack_lsetlabel(dest_path.data(), "1", type);
-               }
-               else
-                       ret = smack_lsetlabel(dest_path.data(), label.c_str(), type);
 
-               if (ret)
+               if (copy_label(label, dest_path, type))
                        throw std::runtime_error(
                                "Couldn't set SMACK attributes of destination directory: "s +
                                dest_path.data());
index 8843a87..4d0afe2 100644 (file)
@@ -18,6 +18,7 @@ namespace fs_helpers
        void change_owner_and_group(std::string_view path, const int session_uid, const int group_id);
        void copy_ownership(std::string_view src_path, std::string_view dest_path);
        std::string get_smack_label(std::string_view src_path, smack_label_type type);
+       int copy_label(auto label, auto dest_path, auto type);
        void copy_smack_attributes(std::string_view src_path, std::string_view dest_path);
        bool subsession_exists(const int session_uid, const std::string_view subsession_id);
        void add_user_subsession(const int session_uid, const std::string_view subsession_id);