From bb5273fb5e381cc9f655cec8ca1c77faebc3a40b Mon Sep 17 00:00:00 2001
From: xuxiaozhou1 <xuxiaozhou1@huawei.com>
Date: Fri, 30 Jun 2023 14:29:08 +0800
Subject: [PATCH] fix: adjust the mode of internal generated files

---
 core/libsysmaster/rel/api.rs           | 25 ++++++++++++++++++++-----
 core/libsysmaster/rel/base.rs          |  9 +++++++++
 core/libsysmaster/rel/history.rs       | 11 ++++++++++-
 core/sysmaster/unit/notify.rs          | 10 +++++++++-
 core/sysmaster/unit/util/unit_file.rs  |  4 ++--
 init/src/runtime/comm.rs               | 16 ++++++++++++++--
 libs/basic/src/path_lookup.rs          | 18 +++++++++++-------
 tests/common/util_lib.sh               |  6 +++---
 8 files changed, 104 insertions(+), 45 deletions(-)

diff --git a/core/libsysmaster/rel/api.rs b/core/libsysmaster/rel/api.rs
index fb482b8..94f9015 100644
--- a/core/libsysmaster/rel/api.rs
+++ b/core/libsysmaster/rel/api.rs
@@ -21,6 +21,7 @@ use super::{
 use crate::{error::*, rel::base};
 use basic::do_entry_or_return_io_error;
 use heed::Database;
+use nix::sys::stat::{self, Mode};
 use std::{
     fs::{self, File},
     path::Path,
@@ -396,17 +397,31 @@ fn reli_prepare() -> Result<String> {
     base::reli_dir_prepare()?; // again
     let dir_string = base::reli_dir_get().unwrap();
 
+    // prepare
+    /* create '/run/sysmaster/reliability/sub_dir' or 'xxx/reliability/sub_dir' with mode 700 */
+    let old_mask = stat::umask(Mode::from_bits_truncate(!0o700));
+    let ret = reli_do_prepare(&dir_string);
+    let _ = stat::umask(old_mask);
+    if let Err(e) = ret {
+        log::error!("reliability prepare failed: dir{:?}, {}", dir_string, e);
+        return Err(e);
+    }
+
+    Ok(dir_string)
+}
+
+fn reli_do_prepare(dir_string: &str) -> Result<()> {
     // enable
-    enable::prepare(&dir_string)?;
+    enable::prepare(dir_string)?;
 
     // last
-    last::prepare(&dir_string)?;
+    last::prepare(dir_string)?;
 
     // history
-    history::prepare(&dir_string)?;
+    history::prepare(dir_string)?;
 
     // pending
-    pending::prepare(&dir_string)?;
+    pending::prepare(dir_string)?;
 
-    Ok(dir_string)
+    Ok(())
 }
diff --git a/core/libsysmaster/rel/base.rs b/core/libsysmaster/rel/base.rs
index 7137e13..65307e0 100644
--- a/core/libsysmaster/rel/base.rs
+++ b/core/libsysmaster/rel/base.rs
@@ -15,6 +15,7 @@ use crate::error::*;
 use heed::types::SerdeBincode;
 use heed::Database;
 use heed::{Env, RoTxn, RwTxn};
+use nix::sys::stat::{self, Mode};
 use serde::de::DeserializeOwned;
 use serde::Serialize;
 use std::cell::RefCell;
@@ -305,6 +306,14 @@ pub fn reli_dir_get() -> Result<String> {
 /// 2. OUT_DIR/../reliability/: make CI happy, which is target/debug/reliability/ or target/release/reliability/ usually.
 /// 3. PROCESS_RELI_PATH: the path customized.
 pub fn reli_dir_prepare() -> Result<()> {
+    // create '/run/sysmaster/reliability' or 'xxx/reliability' with mode 700
+    let old_mask = stat::umask(Mode::from_bits_truncate(!0o700));
+    let ret = reli_dir_prepare_body();
+    let _ = stat::umask(old_mask);
+    ret
+}
+
+fn reli_dir_prepare_body() -> Result<()> {
     // // /run/sysmaster/reliability/
     let ret_run = reli_dir_prepare_run();
     if ret_run.is_ok() {
diff --git a/core/libsysmaster/rel/history.rs b/core/libsysmaster/rel/history.rs
index fc31623..c301f38 100644
--- a/core/libsysmaster/rel/history.rs
+++ b/core/libsysmaster/rel/history.rs
@@ -14,6 +14,7 @@ use super::base::{ReDbRoTxn, ReDbRwTxn, ReDbTable};
 use crate::error::*;
 use basic::{do_entry_log, do_entry_or_return_io_error};
 use heed::{CompactionOption, Env, EnvOpenOptions};
+use nix::sys::stat::{self, Mode};
 use std::cell::RefCell;
 use std::collections::HashMap;
 use std::fmt;
@@ -120,6 +121,14 @@ impl ReliHistory {
     }
 
     pub(super) fn compact(&self) -> Result<()> {
+        // action with mode 700, excluding group and other users
+        let old_mask = stat::umask(Mode::from_bits_truncate(!0o700));
+        let ret = self.compact_body();
+        let _ = stat::umask(old_mask);
+        ret
+    }
+
+    fn compact_body(&self) -> Result<()> {
         // a -> b or b -> a
         // prepare next
         let history = history_path_get(&self.hdir);
@@ -189,7 +198,7 @@ pub fn prepare(dir_str: &str) -> Result<()> {
 
     let b = history.join(RELI_HISTORY_B_DIR);
     if !b.exists() {
-        do_entry_or_return_io_error!(fs::create_dir_all, a, "create");
+        do_entry_or_return_io_error!(fs::create_dir_all, b, "create");
     }
 
     Ok(())
diff --git a/core/sysmaster/unit/notify.rs b/core/sysmaster/unit/notify.rs
index d23a725..4f92b63 100644
--- a/core/sysmaster/unit/notify.rs
+++ b/core/sysmaster/unit/notify.rs
@@ -21,6 +21,7 @@ use nix::errno::Errno;
 use nix::sys::socket::{
     self, sockopt, AddressFamily, MsgFlags, RecvMsg, SockFlag, SockType, UnixAddr, UnixCredentials,
 };
+use nix::sys::stat::{self, Mode};
 use nix::unistd::Pid;
 use std::{
     cell::RefCell, collections::HashMap, fs, io::IoSliceMut, os::unix::prelude::RawFd,
@@ -171,7 +172,14 @@ impl Notify {
             log::warn!("unlink path failed: {:?}, error: {}", sock_path, e);
         }
 
-        socket::bind(fd, &unix_addr)?;
+        // create '/run/sysmaster/notify' with mode 666
+        let old_mask = stat::umask(Mode::from_bits_truncate(!0o666));
+        let ret = socket::bind(fd, &unix_addr);
+        let _ = stat::umask(old_mask);
+        if let Err(e) = ret {
+            log::error!("Failed to bind socket {:?}: {}", sock_path, e);
+            return Err(e);
+        }
         socket::setsockopt(fd, sockopt::PassCred, &true)?;
 
         log::debug!("set event fd is: {}", fd);
diff --git a/core/sysmaster/unit/util/unit_file.rs b/core/sysmaster/unit/util/unit_file.rs
index eb9404b..4f7078f 100644
--- a/core/sysmaster/unit/util/unit_file.rs
+++ b/core/sysmaster/unit/util/unit_file.rs
@@ -105,7 +105,7 @@ impl UnitFileData {
         if fs::metadata(path).is_err() {
             return None;
         }
-        /* {/etc/sysmaster, /usr/lib/sysmaster}/foo.service.d */
+        /* {/etc/sysmaster/system, /usr/lib/sysmaster/system}/foo.service.d */
         let pathd_str = format!("{path}/{name}.d");
         let dir = Path::new(&pathd_str);
         if dir.is_dir() {
@@ -121,7 +121,7 @@ impl UnitFileData {
                 res.push(fragment);
             }
         }
-        /* {/etc/sysmater, /usr/lib/sysmaster}/foo.service */
+        /* {/etc/sysmater/system, /usr/lib/sysmaster/system}/foo.service */
         let config_path = Path::new(path).join(name);
         if !config_path.exists() {
             return None;
diff --git a/init/src/runtime/comm.rs b/init/src/runtime/comm.rs
index 92d52bc..c285ad7 100644
--- a/init/src/runtime/comm.rs
+++ b/init/src/runtime/comm.rs
@@ -16,6 +16,7 @@ use nix::errno::Errno;
 use nix::sys::epoll::EpollEvent;
 use nix::sys::inotify::{AddWatchFlags, InitFlags, Inotify, WatchDescriptor};
 use nix::sys::socket::{self, AddressFamily, SockFlag, SockType, UnixAddr};
+use nix::sys::stat::{self, Mode};
 use nix::unistd;
 use std::os::unix::io::AsRawFd;
 use std::os::unix::prelude::RawFd;
@@ -281,12 +282,16 @@ fn create_listen_fd(epoll: &Rc<Epoll>) -> Result<(i32, Inotify, WatchDescriptor)
         None,
     )?;
 
+    // create '/run/sysmaster' with mode 755
     let sock_path = PathBuf::from(INIT_SOCKET);
     let path = match sock_path.as_path().parent() {
         None => return Err(Errno::EINVAL),
         Some(v) => v,
     };
-    if let Err(e) = fs::create_dir_all(path) {
+    let old_mask = stat::umask(Mode::from_bits_truncate(!0o755));
+    let ret = fs::create_dir_all(path);
+    let _ = stat::umask(old_mask);
+    if let Err(e) = ret {
         eprintln!("Failed to create directory {path:?}: {e}");
         return Err(Errno::from_i32(
             e.raw_os_error().unwrap_or(Errno::EINVAL as i32),
@@ -297,8 +302,15 @@ fn create_listen_fd(epoll: &Rc<Epoll>) -> Result<(i32, Inotify, WatchDescriptor)
         eprintln!("Failed to unlink path:{:?}, error:{}", sock_path, e);
     }
 
+    // create '/run/sysmaster/init' with mode 600
     let addr = UnixAddr::new(&sock_path)?;
-    socket::bind(listen_fd, &addr)?;
+    let old_mask = stat::umask(Mode::from_bits_truncate(!0o600));
+    let ret = socket::bind(listen_fd, &addr);
+    let _ = stat::umask(old_mask);
+    if let Err(e) = ret {
+        eprintln!("Failed to bind socket {sock_path:?}: {e}");
+        return Err(e);
+    }
     socket::listen(listen_fd, LISTEN_BACKLOG)?;
 
     let inotify = Inotify::init(InitFlags::all())?;
diff --git a/libs/basic/src/path_lookup.rs b/libs/basic/src/path_lookup.rs
index 4c9797d..e3ab1f2 100644
--- a/libs/basic/src/path_lookup.rs
+++ b/libs/basic/src/path_lookup.rs
@@ -13,11 +13,11 @@
 //! the management of the unit file lookup path
 
 /// unit lookup path in /etc
-pub const ETC_SYSTEM_PATH: &str = "/etc/sysmaster";
+pub const ETC_SYSTEM_PATH: &str = "/etc/sysmaster/system";
 /// unit lookup path in /run
-pub const RUN_SYSTEM_PATH: &str = "/run/sysmaster";
+pub const RUN_SYSTEM_PATH: &str = "/run/sysmaster/system";
 /// unit lookup path in /usr/lib
-pub const LIB_SYSTEM_PATH: &str = "/usr/lib/sysmaster";
+pub const LIB_SYSTEM_PATH: &str = "/usr/lib/sysmaster/system";
 
 /// struct LookupPaths
 #[derive(Debug, Clone)]
@@ -85,15 +85,19 @@ mod tests {
         lp.init_lookup_paths();
         assert_eq!(
             lp.search_path,
-            vec!["/usr/lib/sysmaster", "/run/sysmaster", "/etc/sysmaster"]
+            vec![
+                "/usr/lib/sysmaster/system",
+                "/run/sysmaster/system",
+                "/etc/sysmaster/system"
+            ]
         );
         assert_eq!(
             lp.preset_path,
             vec![
-                "/etc/sysmaster/system-preset",
-                "/usr/lib/sysmaster/system-preset"
+                "/etc/sysmaster/system/system-preset",
+                "/usr/lib/sysmaster/system/system-preset"
             ]
         );
-        assert_eq!(lp.persistent_path, "/etc/sysmaster")
+        assert_eq!(lp.persistent_path, "/etc/sysmaster/system")
     }
 }
diff --git a/tests/common/util_lib.sh b/tests/common/util_lib.sh
index 1878016..18de448 100644
--- a/tests/common/util_lib.sh
+++ b/tests/common/util_lib.sh
@@ -1,9 +1,9 @@
 #!/usr/bin/env bash
 
 export EXPECT_FAIL=0
-export SYSMST_LIB_PATH='/usr/lib/sysmaster'
-export SYSMST_ETC_PATH='/etc/sysmaster'
-export SYSMST_RUN_PATH='/run/sysmaster'
+export SYSMST_LIB_PATH='/usr/lib/sysmaster/system'
+export SYSMST_ETC_PATH='/etc/sysmaster/system'
+export SYSMST_RUN_PATH='/run/sysmaster/system'
 export SYSMST_LOG='/opt/sysmaster.log'
 export RELIAB_SWITCH_PATH='/run/sysmaster/reliability'
 export RELIAB_SWITCH='switch.debug'
-- 
2.33.0

