If you want to add the TIZEN_ASAN_ACTIVATION environment variable when launching a certain app,
add the appid to the /opt/usr/share/aul/debug/.asan_app_list.
Change-Id: I7eba02d0a7f0afd9ad7588526ba9e923a5325d4e
Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "launchpad-process-pool/debug.hh"
+
+#include <fstream>
+
+#include "lib/common/inc/launchpad_common.h"
+
+namespace launchpad {
+
+AsanAppChecker::AsanAppChecker() : file_monitor_(kAsanAppListPath, this) {}
+
+void AsanAppChecker::Update() {
+ asan_app_map_.clear();
+ std::ifstream if_stream;
+ if_stream.open(kAsanAppListPath);
+ if (!if_stream.is_open()) {
+ _E("Failed to open %s", kAsanAppListPath);
+ return;
+ }
+
+ std::string appid;
+ while (!if_stream.eof()) {
+ if_stream >> appid;
+ asan_app_map_.insert(std::move(appid));
+ }
+}
+
+bool AsanAppChecker::CheckAsanApp(const std::string& appid) const {
+ return asan_app_map_.find(appid) != asan_app_map_.end();
+}
+
+void AsanAppChecker::OnFileChanged(
+ launchpad::FileMonitor::FileMonitorEvent event) {
+ _W("%s was changed. event(%d)", kAsanAppListPath, static_cast<int>(event));
+ Update();
+}
+
+} // namespace launchpad
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DEBUG_HH_
+#define DEBUG_HH_
+
+#include <string>
+#include <unordered_set>
+
+#include <launchpad-process-pool/file_monitor.hh>
+
+namespace launchpad {
+
+class AsanAppChecker : public launchpad::FileMonitor::IEvent {
+ public:
+ AsanAppChecker();
+ bool CheckAsanApp(const std::string& appid) const;
+
+ private:
+ void Update();
+ void OnFileChanged(launchpad::FileMonitor::FileMonitorEvent event) override;
+
+ std::unordered_set<std::string> asan_app_map_;
+ static constexpr const char kAsanAppListPath[] =
+ "/opt/usr/share/aul/debug/.asan_app_list";
+ launchpad::FileMonitor file_monitor_;
+};
+
+} // namespace launchpad
+
+#endif // DEBUG_HH_
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "launchpad-process-pool/file_monitor.hh"
+
+#include "lib/common/inc/launchpad_common.h"
+
+namespace launchpad {
+
+namespace fs = std::filesystem;
+
+gboolean FileMonitor::OnEventReceived(GIOChannel* channel,
+ GIOCondition cond,
+ gpointer user_data) {
+ char buf[4096] __attribute__((aligned(__alignof__(struct inotify_event))));
+ char* ptr;
+ ssize_t len;
+ struct inotify_event* event;
+ auto event_listener = reinterpret_cast<FileMonitor*>(user_data);
+ int fd = g_io_channel_unix_get_fd(channel);
+
+ while ((len = read(fd, buf, sizeof(buf))) > 0) {
+ for (ptr = buf; ptr < buf + len;
+ ptr += sizeof(struct inotify_event) + event->len) {
+ event = reinterpret_cast<struct inotify_event*>(ptr);
+ char* nptr = ptr + sizeof(struct inotify_event) + event->len;
+ if (nptr > buf + len)
+ break;
+
+ if (!event->len || event_listener->file_name_ != event->name)
+ continue;
+
+ if (event->mask & IN_CREATE) {
+ if (event_listener->listener_)
+ event_listener->listener_->OnFileChanged(FileMonitorEvent::Created);
+ } else if (event->mask & IN_MODIFY) {
+ if (event_listener->listener_)
+ event_listener->listener_->OnFileChanged(FileMonitorEvent::Modified);
+ } else if (event->mask & IN_DELETE) {
+ if (event_listener->listener_)
+ event_listener->listener_->OnFileChanged(FileMonitorEvent::Deleted);
+ }
+
+ return G_SOURCE_CONTINUE;
+ }
+ }
+
+ return G_SOURCE_CONTINUE;
+}
+
+FileMonitor::FileMonitor(const std::string_view file_path,
+ FileMonitor::IEvent* listener)
+ : listener_(listener) {
+ fs::path path(file_path);
+ parent_path_ = path.parent_path();
+ file_name_ = path.filename();
+ if (!fs::exists(parent_path_)) {
+ if (!fs::create_directories(parent_path_)) {
+ _E("Failed to create directory. %s", parent_path_.c_str());
+ return;
+ }
+ }
+
+ if (fs::exists(path)) {
+ if (listener_)
+ listener_->OnFileChanged(FileMonitor::FileMonitorEvent::Created);
+ }
+
+ fd_ = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+ if (fd_ == -1) {
+ int ret = errno;
+ _E("Failed to inotify_init. errno: %d", ret);
+ disposed_ = true;
+ return;
+ }
+
+ wd_ = inotify_add_watch(fd_, parent_path_.c_str(),
+ IN_CREATE | IN_MODIFY | IN_DELETE);
+ if (wd_ == -1) {
+ int ret = errno;
+ _E("Failed to inotify_add_watch. errno: %d", ret);
+ Dispose();
+ return;
+ }
+
+ channel_ = g_io_channel_unix_new(fd_);
+ if (channel_ == nullptr) {
+ _E("Failed to create GIO channel");
+ Dispose();
+ return;
+ }
+
+ g_io_channel_set_close_on_unref(channel_, false);
+ tag_ = g_io_add_watch(channel_, G_IO_IN, OnEventReceived, this);
+ if (tag_ == 0) {
+ _E("Failed to add watch");
+ Dispose();
+ return;
+ }
+
+ disposed_ = false;
+}
+
+FileMonitor::~FileMonitor() {
+ Dispose();
+}
+
+void FileMonitor::Dispose() {
+ if (disposed_)
+ return;
+
+ if (tag_) {
+ g_source_remove(tag_);
+ tag_ = 0;
+ }
+
+ if (channel_ != nullptr) {
+ g_io_channel_unref(channel_);
+ channel_ = nullptr;
+ }
+
+ if (wd_ > 0) {
+ inotify_rm_watch(fd_, wd_);
+ wd_ = 0;
+ }
+
+ if (fd_ > 0) {
+ close(fd_);
+ fd_ = 0;
+ }
+
+ disposed_ = true;
+}
+
+} // namespace launchpad
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FILE_MONITOR_
+#define FILE_MONITOR_
+
+#include <gio/gio.h>
+#include <glib.h>
+#include <sys/inotify.h>
+
+#include <filesystem>
+#include <string_view>
+
+namespace launchpad {
+
+class FileMonitor {
+ public:
+ enum class FileMonitorEvent : int {
+ Created = IN_CREATE,
+ Modified = IN_MODIFY,
+ Deleted = IN_DELETE,
+ };
+
+ class IEvent {
+ public:
+ virtual void OnFileChanged(FileMonitorEvent event) = 0;
+ };
+
+ FileMonitor(const std::string_view file_path, IEvent* listener);
+ ~FileMonitor();
+ FileMonitor(const FileMonitor&) = delete;
+ FileMonitor& operator=(const FileMonitor&) = delete;
+
+ private:
+ std::filesystem::path parent_path_;
+ std::filesystem::path file_name_;
+ int fd_ = 0;
+ int wd_ = 0;
+ GIOChannel* channel_ = nullptr;
+ int tag_ = 0;
+ bool disposed_ = false;
+ IEvent* listener_;
+
+ void Dispose();
+ static gboolean OnEventReceived(GIOChannel* channel,
+ GIOCondition cond,
+ gpointer user_data);
+};
+
+} // namespace launchpad
+
+#endif // FILE_MONITOR_
#include <algorithm>
+#include "launchpad-process-pool/debug.hh"
#include "launchpad-process-pool/launcher_info.hh"
#include "launchpad-process-pool/launchpad_config.h"
#include "launchpad-process-pool/launchpad_dbus.h"
io_channel_h __launchpad_channel;
int __client_fd = -1;
worker_h __cleaner;
+launchpad::AsanAppChecker __asan_app_checker;
} // namespace
if (bundle_get_type(launch_arg->kb, AUL_K_SDK) != BUNDLE_TYPE_NONE)
_debug_prepare_debugger(launch_arg->kb);
+ if (__asan_app_checker.CheckAsanApp(launch_arg->appid)) {
+ _W("%s TIZEN_ASAN_ACTIVATION", launch_arg->appid);
+ setenv("TIZEN_ASAN_ACTIVATION", "1", 1);
+ }
+
_signal_unblock_sigchld();
_delete_sock_path(getpid(), getuid());
}
static int __launch_request_do(request_h request) {
- if (request->loader_id == PAD_LOADER_ID_DIRECT || request->cpc == nullptr) {
+ if (request->loader_id == PAD_LOADER_ID_DIRECT || request->cpc == nullptr ||
+ __asan_app_checker.CheckAsanApp(request->menu_info->appid)) {
__fork_processing(request);
return 0;
}
#include <sys/types.h>
#include <algorithm>
+#include <fstream>
+#include <utility>
#include "launchpad-process-pool/debugger_info.hh"
#include "lib/common/inc/key.h"