Add to enable TIZEN_ASAN_ACTIVATION 04/288804/18
authorChanggyu Choi <changyu.choi@samsung.com>
Thu, 23 Feb 2023 08:10:28 +0000 (17:10 +0900)
committerChanggyu Choi <changyu.choi@samsung.com>
Thu, 9 Mar 2023 06:36:37 +0000 (06:36 +0000)
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>
src/launchpad-process-pool/debug.cc [new file with mode: 0644]
src/launchpad-process-pool/debug.hh [new file with mode: 0644]
src/launchpad-process-pool/file_monitor.cc [new file with mode: 0644]
src/launchpad-process-pool/file_monitor.hh [new file with mode: 0644]
src/launchpad-process-pool/launchpad.cc
src/launchpad-process-pool/launchpad_debug.cc

diff --git a/src/launchpad-process-pool/debug.cc b/src/launchpad-process-pool/debug.cc
new file mode 100644 (file)
index 0000000..0d2f90b
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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
diff --git a/src/launchpad-process-pool/debug.hh b/src/launchpad-process-pool/debug.hh
new file mode 100644 (file)
index 0000000..d0ae3a1
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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_
diff --git a/src/launchpad-process-pool/file_monitor.cc b/src/launchpad-process-pool/file_monitor.cc
new file mode 100644 (file)
index 0000000..594c56a
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * 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
diff --git a/src/launchpad-process-pool/file_monitor.hh b/src/launchpad-process-pool/file_monitor.hh
new file mode 100644 (file)
index 0000000..d0c680d
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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_
index ed0a39a..3bca3e8 100644 (file)
@@ -40,6 +40,7 @@
 
 #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"
@@ -219,6 +220,7 @@ io_channel_h __label_monitor_channel;
 io_channel_h __launchpad_channel;
 int __client_fd = -1;
 worker_h __cleaner;
+launchpad::AsanAppChecker __asan_app_checker;
 
 }  // namespace
 
@@ -1387,6 +1389,11 @@ static int __exec_app_process(void* arg) {
   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());
@@ -2525,7 +2532,8 @@ static void __fork_processing(request_h request) {
 }
 
 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;
   }
index d94c194..73a7604 100644 (file)
@@ -28,6 +28,8 @@
 #include <sys/types.h>
 
 #include <algorithm>
+#include <fstream>
+#include <utility>
 
 #include "launchpad-process-pool/debugger_info.hh"
 #include "lib/common/inc/key.h"