From: Hwankyu Jhun Date: Wed, 23 Oct 2024 01:11:34 +0000 (+0900) Subject: Fix a timing issue of app labels changed event X-Git-Tag: accepted/tizen/unified/x/20241023.091608~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fd3b23c303a8b718cb86d9d6712363da5bc6ebd9;p=platform%2Fcore%2Fappfw%2Flaunchpad.git Fix a timing issue of app labels changed event If the launchpad-process-pool receives app labels changed event before the lux, it causes the failure issue of calling the security_manager_prepare_app2(). When getting the app labels changed event, the lux notifies that to the launchpad-process-pool. And then, the launchpad-process-pool kills and executes the loader processes. Change-Id: Idb8fb7e812a1467c8702e07c2fb06e09a3ff963b Signed-off-by: Hwankyu Jhun --- diff --git a/src/launchpad-process-pool/launchpad.cc b/src/launchpad-process-pool/launchpad.cc index 4203658e..3250803d 100644 --- a/src/launchpad-process-pool/launchpad.cc +++ b/src/launchpad-process-pool/launchpad.cc @@ -691,6 +691,10 @@ void Launchpad::OnLuxSigchld(pid_t pid, int status) { SignalManager::GetInst().HandleSigchld(pid, status); } +void Launchpad::OnLuxAppLabelsChanged() { + LoaderManager::GetInst().HandleAppLabelsChanged(); +} + void Launchpad::OnLoaderPrepared(LoaderContext* loader_context) { _W("Loader is prepared. name(%s), pid(%d)", loader_context->GetLoaderName().c_str(), loader_context->GetPid()); diff --git a/src/launchpad-process-pool/launchpad.hh b/src/launchpad-process-pool/launchpad.hh index 89b72fe9..24244ead 100644 --- a/src/launchpad-process-pool/launchpad.hh +++ b/src/launchpad-process-pool/launchpad.hh @@ -95,6 +95,7 @@ class Launchpad : public IOChannel::IEvent, void OnLoaderPrepared(LoaderContext* loader_context) override; void OnLoaderLaunched(LoaderContext* loader_context) override; void OnLuxSigchld(pid_t pid, int status) override; + void OnLuxAppLabelsChanged() override; private: int argc_; diff --git a/src/launchpad-process-pool/loader_manager.cc b/src/launchpad-process-pool/loader_manager.cc index f7b42713..9df3f57b 100644 --- a/src/launchpad-process-pool/loader_manager.cc +++ b/src/launchpad-process-pool/loader_manager.cc @@ -435,7 +435,7 @@ LoaderManager::LoaderManager() : sequencer_(new Sequencer(this)) {} LoaderManager::~LoaderManager() { Dispose(); } -void LoaderManager::OnAppLabelsChanged() { +void LoaderManager::HandleAppLabelsChanged() { _W("BEGIN"); LoaderExecutor::GetInst().DisposeCandidateProcess(); for (auto& context : loader_contexts_) { @@ -459,6 +459,8 @@ void LoaderManager::OnAppLabelsChanged() { _W("END"); } +void LoaderManager::OnAppLabelsChanged() {} + void LoaderManager::OnMemoryStatusChanged(bool low_memory, bool should_check_pss) { if (should_check_pss) diff --git a/src/launchpad-process-pool/loader_manager.hh b/src/launchpad-process-pool/loader_manager.hh index a433670d..065b77b8 100644 --- a/src/launchpad-process-pool/loader_manager.hh +++ b/src/launchpad-process-pool/loader_manager.hh @@ -83,6 +83,7 @@ class LoaderManager : public AppDefinedLoaderInfoManager::IEvent, std::shared_ptr FindLoaderContextFromName( const std::string& loader_name); std::shared_ptr FindLoaderContextFromPid(pid_t pid); + void HandleAppLabelsChanged(); private: LoaderManager(); diff --git a/src/launchpad-process-pool/lux_manager.cc b/src/launchpad-process-pool/lux_manager.cc index 946f8ff0..cb041fb1 100644 --- a/src/launchpad-process-pool/lux_manager.cc +++ b/src/launchpad-process-pool/lux_manager.cc @@ -47,14 +47,6 @@ void LuxManager::Init() { if (!Prepare()) return; - try { - sigchld_channel_.reset(new IOChannel(sigchld_socket_->GetFd(), - IOChannel::IOCondition::IO_IN, this)); - } catch (const Exception& e) { - _E("Exception occurs. error=%s", e.what()); - return; - } - disposed_ = false; } @@ -62,55 +54,121 @@ void LuxManager::Dispose() { if (disposed_) return; Kill(); - sigchld_channel_.reset(); - sigchld_socket_.reset(); - read_socket_.reset(); - write_socket_.reset(); + IgnoreEvents(); + ClosePipeFds(); disposed_ = true; } -bool LuxManager::Prepare() { - if (pid_ > 0) return false; +bool LuxManager::PreparePipeFds() { + read_fd_ = -1; + write_fd_ = -1; + sigchld_fd_ = -1; + label_monitor_fd_ = -1; int pipe_fd[2]; if (CreatePipe(&pipe_fd) != 0) return false; read_socket_.reset(new Socket(pipe_fd[0])); - int write_fd = pipe_fd[1]; + write_fd_ = pipe_fd[1]; if (CreatePipe(&pipe_fd) != 0) { - close(write_fd); + ClosePipeFds(); return false; } - int read_fd = pipe_fd[0]; + read_fd_ = pipe_fd[0]; write_socket_.reset(new Socket(pipe_fd[1])); if (CreatePipe(&pipe_fd) != 0) { - close(read_fd); - close(write_fd); + ClosePipeFds(); return false; } - int sigchld_fd = pipe_fd[0]; + sigchld_fd_ = pipe_fd[0]; sigchld_socket_.reset(new Socket(pipe_fd[1])); - _W("read_socket=%d, write_socket=%d, sigchld_socket=%d", - read_socket_->GetFd(), write_socket_->GetFd(), sigchld_socket_->GetFd()); + if (CreatePipe(&pipe_fd) != 0) { + ClosePipeFds(); + return false; + } + + label_monitor_fd_ = pipe_fd[0]; + label_monitor_socket_.reset(new Socket(pipe_fd[1])); + return true; +} + +void LuxManager::ClosePipeFds() { + if (label_monitor_fd_ > -1) { + close(label_monitor_fd_); + label_monitor_fd_ = -1; + } + + if (sigchld_fd_ > -1) { + close(sigchld_fd_); + sigchld_fd_ = -1; + } + + if (read_fd_ > -1) { + close(read_fd_); + read_fd_ = -1; + } + + if (write_fd_ > -1) { + close(write_fd_); + write_fd_ = -1; + } + + label_monitor_socket_.reset(); + sigchld_socket_.reset(); + read_socket_.reset(); + write_socket_.reset(); +} + +bool LuxManager::ListenEvents() { + try { + sigchld_channel_.reset(new IOChannel(sigchld_socket_->GetFd(), + IOChannel::IOCondition::IO_IN, this)); + label_monitor_channel_.reset(new IOChannel( + label_monitor_socket_->GetFd(), IOChannel::IOCondition::IO_IN, this)); + } catch (const Exception& e) { + _E("Exception occurs. error=%s", e.what()); + return false; + } + + return true; +} + +void LuxManager::IgnoreEvents() { + sigchld_channel_.reset(); + label_monitor_channel_.reset(); +} + +bool LuxManager::Prepare() { + if (pid_ > 0) return false; + + if (!PreparePipeFds()) return false; + + _W("read_socket=%d, write_socket=%d, sigchld_socket=%d, " + "label_monitor_socket=%d", + read_socket_->GetFd(), write_socket_->GetFd(), sigchld_socket_->GetFd(), + label_monitor_socket_->GetFd()); pid_ = Executor::Execute(); if (pid_ < 0) { _E("Failed to execute lux. errno(%d)", errno); - close(sigchld_fd); - close(read_fd); - close(write_fd); + ClosePipeFds(); return false; } _W("Lux process=%d", pid_); - sigchld_socket_.reset(new Socket(sigchld_fd)); - read_socket_.reset(new Socket(read_fd)); - write_socket_.reset(new Socket(write_fd)); - return true; + label_monitor_socket_.reset(new Socket(label_monitor_fd_)); + label_monitor_fd_ = -1; + sigchld_socket_.reset(new Socket(sigchld_fd_)); + sigchld_fd_ = -1; + read_socket_.reset(new Socket(read_fd_)); + read_fd_ = -1; + write_socket_.reset(new Socket(write_fd_)); + write_fd_ = -1; + return ListenEvents(); } bool LuxManager::IsPrepared() const { @@ -146,10 +204,8 @@ pid_t LuxManager::SendAndReceive(const tizen_base::Parcel& parcel) { void LuxManager::HandleSigchld(pid_t pid) { if (pid_ != pid) return; - sigchld_channel_.reset(); - sigchld_socket_.reset(); - read_socket_.reset(); - write_socket_.reset(); + IgnoreEvents(); + ClosePipeFds(); pid_ = -1; Prepare(); } @@ -187,8 +243,8 @@ void LuxManager::Kill() { pid_ = -1; } -void LuxManager::OnIOEventReceived(int fd, int condition) { - _D("fd=%d, condition=%d", fd, condition); + +void LuxManager::HandleSigChldEvent() { size_t data_size = 0; int ret = sigchld_socket_->Read(static_cast(&data_size), sizeof(data_size)); @@ -213,19 +269,50 @@ void LuxManager::OnIOEventReceived(int fd, int condition) { if (listener_) listener_->OnLuxSigchld(pid, status); } +void LuxManager::HandleAppLabelsChangedEvent() { + size_t data_size = 0; + int ret = label_monitor_socket_->Read(static_cast(&data_size), + sizeof(data_size)); + if (ret != 0) { + _E("Failed to receive the data. error=%d", ret); + return; + } + + std::vector data(data_size); + ret = label_monitor_socket_->Read(data.data(), data_size); + if (ret != 0) { + _E("Failed to receive the data. error=%d", ret); + return; + } + + tizen_base::Parcel parcel(data.data(), data.size()); + parcel.ReadInt32(&ret); + _W("[AppLabelsChanged] ret=%d", ret); + if (listener_) listener_->OnLuxAppLabelsChanged(); +} + +void LuxManager::OnIOEventReceived(int fd, int condition) { + _D("fd=%d, condition=%d", fd, condition); + if (fd == sigchld_socket_->GetFd()) HandleSigChldEvent(); + else if (fd == label_monitor_socket_->GetFd()) HandleAppLabelsChangedEvent(); +} + void LuxManager::OnExecution() { CPUBoostController::DoBoost(getpid(), CPUBoostController::Level::Strong, -1, true); std::vector except_fds{read_socket_->GetFd(), write_socket_->GetFd(), - sigchld_socket_->GetFd()}; + sigchld_socket_->GetFd(), + label_monitor_socket_->GetFd()}; Util::CloseAllFds(except_fds); std::string rfd = std::to_string(read_socket_->RemoveFd()); std::string wfd = std::to_string(write_socket_->RemoveFd()); std::string sfd = std::to_string(sigchld_socket_->RemoveFd()); + std::string lfd = std::to_string(label_monitor_socket_->RemoveFd()); setenv("LUX_READ_FD", rfd.c_str(), 1); setenv("LUX_WRITE_FD", wfd.c_str(), 1); setenv("LUX_SIGCHLD_FD", sfd.c_str(), 1); + setenv("LUX_LABEL_MONITOR_FD", lfd.c_str(), 1); std::vector args; args.push_back(const_cast(kPathLux)); diff --git a/src/launchpad-process-pool/lux_manager.hh b/src/launchpad-process-pool/lux_manager.hh index 0c5ddae2..18bfbfca 100644 --- a/src/launchpad-process-pool/lux_manager.hh +++ b/src/launchpad-process-pool/lux_manager.hh @@ -38,6 +38,7 @@ class LuxManager : public IOChannel::IEvent, public: virtual ~IEvent() = default; virtual void OnLuxSigchld(pid_t pid, int status) = 0; + virtual void OnLuxAppLabelsChanged() = 0; }; LuxManager(const LuxManager&) = delete; @@ -59,10 +60,16 @@ class LuxManager : public IOChannel::IEvent, LuxManager(); ~LuxManager(); + bool PreparePipeFds(); + void ClosePipeFds(); + bool ListenEvents(); + void IgnoreEvents(); int CreatePipe(int (*pipe_fd)[2]); void Kill(); void HandleServerEvent(); void HandleClientEvent(int condition); + void HandleSigChldEvent(); + void HandleAppLabelsChangedEvent(); void OnIOEventReceived(int fd, int condition) override; void OnExecution() override; @@ -74,6 +81,12 @@ class LuxManager : public IOChannel::IEvent, std::unique_ptr write_socket_; std::unique_ptr sigchld_socket_; std::unique_ptr sigchld_channel_; + std::unique_ptr label_monitor_socket_; + std::unique_ptr label_monitor_channel_; + int read_fd_ = -1; + int write_fd_ = -1; + int sigchld_fd_ = -1; + int label_monitor_fd_ = -1; }; } // namespace launchpad diff --git a/src/lux/src/lux/app_labels_monitor.rs b/src/lux/src/lux/app_labels_monitor.rs index 30d6fb25..a7585ca0 100644 --- a/src/lux/src/lux/app_labels_monitor.rs +++ b/src/lux/src/lux/app_labels_monitor.rs @@ -21,6 +21,7 @@ extern "C" { pub struct AppLabelsMonitor { handle: *mut c_void, source_id: c_uint, + write_fd: i32, disposed: bool, } @@ -36,22 +37,25 @@ extern "C" fn app_labels_monitor_callback( data: *mut c_void, ) -> glib_sys::gboolean { unsafe { + debug!("BEGIN"); let handle: &mut AppLabelsMonitor = &mut *(data as *mut AppLabelsMonitor); handle.process(); + debug!("END"); G_SOURCE_CONTINUE } } impl AppLabelsMonitor { pub fn new() -> Self { - AppLabelsMonitor { handle: ptr::null_mut(), source_id: 0, disposed: true } + AppLabelsMonitor { handle: ptr::null_mut(), source_id: 0, write_fd: -1, disposed: true } } - pub fn init(&mut self) -> Result<(), ()> { + pub fn init(&mut self, write_fd: i32) -> Result<(), ()> { if !self.disposed { return Ok(()); } + self.write_fd = write_fd; let mut fd: i32 = -1; let ret = unsafe { security_manager_app_labels_monitor_init(&mut self.handle) }; if ret != SECURITY_MANAGER_SUCCESS { @@ -105,10 +109,45 @@ impl AppLabelsMonitor { self.handle = ptr::null_mut(); } } + + if self.write_fd > -1 { + unsafe { + close(self.write_fd); + self.write_fd = -1; + } + } + self.disposed = true; } fn process(&mut self) { - unsafe { security_manager_app_labels_monitor_process(self.handle) }; + let ret = unsafe { security_manager_app_labels_monitor_process(self.handle) }; + let mut parcel = Parcel::new(); + parcel.write_i32(ret as i32); + self.write_parcel(&mut parcel); + } + + fn write_parcel(&mut self, parcel: &mut Parcel) -> Result<(), ()> { + let mut data = parcel.get_raw_data().unwrap(); + let mut data_size: c_ulong = (data.len() as usize).try_into().unwrap(); + let nbytes = unsafe { + write( + self.write_fd, + (&mut data_size as *mut c_ulong).cast::() as *mut c_void, + mem::size_of::(), + ) + }; + if nbytes < 0 { + error!("Failed to write data size"); + return Err(()); + } + + let nbytes = unsafe { write(self.write_fd, data.as_mut_ptr() as *mut _, data.len()) }; + if nbytes < 0 { + error!("Failed to write data"); + return Err(()); + } + + Ok(()) } } diff --git a/src/lux/src/lux/mod.rs b/src/lux/src/lux/mod.rs index 2f79c2a7..66981bbb 100644 --- a/src/lux/src/lux/mod.rs +++ b/src/lux/src/lux/mod.rs @@ -114,7 +114,7 @@ impl Lux { } } - pub fn run(&mut self, read_fd: i32, write_fd: i32, sigchld_fd: i32) -> Result<(), ()> { + pub fn run(&mut self, read_fd: i32, write_fd: i32, sigchld_fd: i32, label_monitor_fd: i32) -> Result<(), ()> { self.read_fd = read_fd; self.write_fd = write_fd; self.sigchld_manager.init(sigchld_fd); @@ -131,7 +131,7 @@ impl Lux { return Err(()); } - self.app_labels_monitor.init(); + self.app_labels_monitor.init(label_monitor_fd); self.region_format_config.listen(); self.language_config.listen(); self.clear_boosting(); diff --git a/src/lux/src/main.rs b/src/lux/src/main.rs index c360bf2e..4427536f 100644 --- a/src/lux/src/main.rs +++ b/src/lux/src/main.rs @@ -23,13 +23,17 @@ fn main() { .ok() .and_then(|fd| fd.parse::().ok()) .unwrap_or(-1); + let label_monitor_fd = env::var("LUX_LABEL_MONITOR_FD") + .ok() + .and_then(|fd| fd.parse::().ok()) + .unwrap_or(-1); - if read_fd < 0 || write_fd < 0 || sigchld_fd < 0 { - print!("Failed to find read/write fds. {read_fd} : {write_fd} : {sigchld_fd}"); + if read_fd < 0 || write_fd < 0 || sigchld_fd < 0 || label_monitor_fd < 0 { + print!("Failed to find read/write fds. {read_fd} : {write_fd} : {sigchld_fd} : {label_monitor_fd}"); std::process::exit(-1); } - debug!("read_fd={}, write_fd={}, sigchld_fd={}", read_fd, write_fd, sigchld_fd); + debug!("read_fd={}, write_fd={}, sigchld_fd={}, label_monitor_fd={}", read_fd, write_fd, sigchld_fd, label_monitor_fd); let mut lux = Lux::new(); - lux.run(read_fd, write_fd, sigchld_fd); + lux.run(read_fd, write_fd, sigchld_fd, label_monitor_fd); }