Modify for checking sender validation 38/309538/5
authorInkyun Kil <inkyun.kil@samsung.com>
Fri, 12 Apr 2024 04:52:09 +0000 (13:52 +0900)
committerInkyun Kil <inkyun.kil@samsung.com>
Thu, 13 Jun 2024 07:26:05 +0000 (16:26 +0900)
- Change the validation of the sender from ESD to the library.
- Bypass checking privilege for not an application with 5001 uid

Change-Id: I72dff501d1f7b1b1422cc3c38c0ec6f602ba7d54
Signed-off-by: Inkyun Kil <inkyun.kil@samsung.com>
CMakeLists.txt
packaging/eventsystem.spec
src/eventsystem.c
tests/unit_tests/CMakeLists.txt
tests/unit_tests/src/test_eventsystem.cc

index 4c7502466cc44e7e3a77533d6693aaca4cabee4e..a8b4f00d97c81fd7e381ed7cff31e0a8d231652d 100644 (file)
@@ -16,7 +16,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src)
 ### Required packages
 INCLUDE(FindPkgConfig)
 
-pkg_check_modules(libpkgs REQUIRED dlog bundle glib-2.0 capi-base-common)
+pkg_check_modules(libpkgs REQUIRED aul dlog bundle glib-2.0 capi-base-common)
 
 #FIND_LIBRARY(LIB_DL dl)
 
index 0d320834c6cca3a6b6b651d6b86390d656dd8c62..1fc60669b1fe2844152663bdeb00e299c3fa37ff 100644 (file)
@@ -6,6 +6,7 @@ Group:      Application Framework/Libraries
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
 BuildRequires:  cmake
+BuildRequires:  pkgconfig(aul)
 BuildRequires:  pkgconfig(ecore)
 BuildRequires:  pkgconfig(bundle)
 BuildRequires:  pkgconfig(dlog)
index 6718303f4bb842ceb141ee46b3c4d8e229f49d26..d127a34fd5b2a37da62c598beffa18d341b57e44 100644 (file)
@@ -11,6 +11,7 @@
 #include <gio/gio.h>
 #include <eventsystem.h>
 #include <fcntl.h>
+#include <aul.h>
 
 #include "eventsystem.h"
 #include "eventsystem_internal.h"
@@ -113,7 +114,7 @@ static sysevent_info_s s_info;
 
 static int __eventsystem_check_user_send_validation(const char *event_name);
 static int __eventsystem_request_destination_list(const char *event_name, GList **dest_list);
-static int __eventsystem_check_sender_validation(int sender_pid,
+static int __eventsystem_check_sender_validation(int sender_pid, uid_t sender_uid,
                const char *event_name, char **sender);
 static eventmap_s *__create_eventmap(const char *interface_name,
                const char *member_name, const char *event_name,
@@ -189,6 +190,45 @@ out:
        return pid;
 }
 
+static uid_t __eventsystem_get_sender_uid(GDBusConnection *conn, const char *sender_name)
+{
+       GDBusMessage *msg = NULL;
+       GDBusMessage *reply = NULL;
+       GError *err = NULL;
+       GVariant *body;
+       uid_t uid = -1;
+
+       msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
+               "org.freedesktop.DBus", "GetConnectionUnixUser");
+       if (!msg) {
+               _E("Can't allocate new method call");
+               goto out;
+       }
+
+       g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
+       reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
+               G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
+
+       if (!reply) {
+               if (err != NULL) {
+                       _E("Failed to get uid [%s]", err->message);
+                       g_error_free(err);
+               }
+               goto out;
+       }
+
+       body = g_dbus_message_get_body(reply);
+       g_variant_get(body, "(u)", &uid);
+
+out:
+       if (msg)
+               g_object_unref(msg);
+       if (reply)
+               g_object_unref(reply);
+
+       return uid;
+}
+
 static char *__get_object_path(char *interface_name)
 {
        int i;
@@ -298,14 +338,14 @@ static char *__get_member_name_from_eventname(char *event_name)
        return member_name;
 }
 
-static int __check_validation_usrevent_sender(int sender_pid,
+static int __check_validation_usrevent_sender(int sender_pid, uid_t sender_uid,
                const char *interface_name, const char *event_name)
 {
        char *sender_id = NULL;
        char *key = NULL;
        char *val = NULL;
 
-       if (__eventsystem_check_sender_validation(sender_pid,
+       if (__eventsystem_check_sender_validation(sender_pid, sender_uid,
                event_name, &sender_id) < 0) {
                _E("invalid user-event sender");
                return ES_R_EINVAL;
@@ -319,7 +359,7 @@ static int __check_validation_usrevent_sender(int sender_pid,
        key = strdup(interface_name);
        if (key == NULL) {
                _E("out of memory");
-               g_free(sender_id);
+               free(sender_id);
                return ES_R_ENOMEM;
        }
 
@@ -327,12 +367,12 @@ static int __check_validation_usrevent_sender(int sender_pid,
        if (val == NULL) {
                _E("out of memory");
                free(key);
-               g_free(sender_id);
+               free(sender_id);
                return ES_R_ENOMEM;
        }
 
        g_hash_table_insert(filter_tbl, key, val);
-       g_free(sender_id);
+       free(sender_id);
 
        return ES_R_OK;
 }
@@ -533,7 +573,7 @@ static void __eventsystem_event_handler(GDBusConnection *connection,
 }
 
 static void __eventsystem_application_event_handler(int sender_pid,
-               const gchar *interface_name, const gchar *signal_name,
+               uid_t sender_uid, const gchar *interface_name, const gchar *signal_name,
                GVariant *parameters, gpointer user_data)
 {
        GList *cb_list;
@@ -552,8 +592,9 @@ static void __eventsystem_application_event_handler(int sender_pid,
                return;
        }
 
-       if (sender_pid > 0 && __check_interface_validation_user((char *)interface_name)) {
-               if (__check_validation_usrevent_sender(sender_pid,
+       if (sender_pid > 0 && sender_uid > 0 &&
+                       __check_interface_validation_user((char *)interface_name)) {
+               if (__check_validation_usrevent_sender(sender_pid, sender_uid,
                        (const char *)interface_name, em->event_name) < 0) {
                        _E("invalid sender");
                        return;
@@ -577,6 +618,7 @@ static void __eventsystem_filter_userevent_for_application(GDBusConnection *conn
 {
        char *sender_id = NULL;
        int sender_pid = -1;
+       uid_t sender_uid = -1;
 
        _D("sender_name(%s), interface_name(%s)", sender_name, interface_name);
 
@@ -593,10 +635,16 @@ static void __eventsystem_filter_userevent_for_application(GDBusConnection *conn
                        g_rec_mutex_unlock(&__rec_mutex);
                        return;
                }
-               _D("sender_pid(%d)", sender_pid);
+
+               sender_uid = __eventsystem_get_sender_uid(connection, sender_name);
+               if (sender_uid <= 0) {
+                       _E("failed to get uid of sender(%s)", sender_name);
+                       return;
+               }
+               _D("sender_pid(%d), sender_uid(%d)", sender_pid, sender_uid);
        }
 
-       __eventsystem_application_event_handler(sender_pid, interface_name,
+       __eventsystem_application_event_handler(sender_pid, sender_uid, interface_name,
                signal_name, parameters, user_data);
 
        g_rec_mutex_unlock(&__rec_mutex);
@@ -614,7 +662,7 @@ static void __eventsystem_filter_sysevent_for_application(GDBusConnection *conne
 
        g_rec_mutex_lock(&__rec_mutex);
 
-       __eventsystem_application_event_handler(-1, interface_name,
+       __eventsystem_application_event_handler(-1, -1, interface_name,
                signal_name, parameters, user_data);
 
        g_rec_mutex_unlock(&__rec_mutex);
@@ -1248,61 +1296,66 @@ out_1:
        return ret;
 }
 
-static int __eventsystem_check_sender_validation(int sender_pid, const char *event_name,
-               char **sender_id)
+static int __check_userevent_name_validation(const char *event_name,
+               const char *app_id)
 {
-       int ret = ES_R_EINVAL;
-       GDBusConnection *conn = NULL;
-       GError *error = NULL;
-       GDBusProxy *proxy = NULL;
-       GVariant *param = NULL;
-       GVariant *value = NULL;
-       gint result = 0;
+       size_t event_name_len;
+       char valid_name[256];
+       size_t last_dot_pos;
 
-       if (!_initialized)
-               __initialize();
+       if (event_name == NULL || app_id == NULL) {
+                       _E("invalid param\n");
+                       return -1;
+       }
 
-       if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
-               _E("getting gdbus-connetion error");
-               ret = ES_R_ERROR;
-               goto out_1;
+       event_name_len = strlen(event_name);
+       if (event_name_len == 0 || event_name_len > 256) {
+               _E("invalid length of event name\n");
+               return -1;
        }
 
-       proxy = g_dbus_proxy_new_sync(conn,
-               G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
-               ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
-               NULL, &error);
-       if (proxy == NULL) {
-               _E("failed to create new proxy, error(%s)", error ? error->message : "");
-               g_error_free(error);
-               ret = ES_R_ERROR;
-               goto out_1;
+       const char *p = strrchr(event_name, '.');
+       if (p == NULL) {
+               return -1;
        }
 
-       param = g_variant_new("(is)", sender_pid, event_name);
-       value = g_dbus_proxy_call_sync(proxy, "CheckSenderValidation", param,
-               G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
-       if (error != NULL) {
-               _E("proxy call sync error(%s)", error->message);
-               g_error_free(error);
-               ret = ES_R_ERROR;
-               goto out_2;
+       last_dot_pos = p - event_name;
+       strncpy(valid_name, event_name, last_dot_pos);
+       valid_name[last_dot_pos] = '\0';
+
+       if (strncmp(valid_name, event_name, strlen(valid_name))!= 0) {
+                       _E("%s is not valid[%s] for appid : %s", event_name, valid_name, app_id);
+                       return -1;
        }
 
-       g_variant_get(value, "(is)", &result, sender_id);
+       return 0;
+}
 
-       _D("result(%d)", result);
+static int __eventsystem_check_sender_validation(int sender_pid,
+               uid_t sender_uid, const char *event_name, char **sender_id)
+{
+       int ret = 0;
+       char app_id[128] = {0, };
 
-       if (result == 1)
-               ret = ES_R_OK;
-out_2:
-       g_object_unref(proxy);
-       g_variant_unref(value);
-out_1:
-       if (conn)
-               g_object_unref(conn);
+       if (!_initialized)
+               __initialize();
 
-       return ret;
+       ret = aul_app_get_appid_bypid_for_uid(sender_pid, app_id, sizeof(app_id), sender_uid);
+       if (ret != AUL_R_OK) {
+               _E("failed to get appid by pid");
+               return ES_R_ERROR;
+       }
+
+       _D("pid(%d)-uid(%d)-appid(%s)", sender_pid, sender_uid, app_id);
+       *sender_id = strdup(app_id);
+
+       if (__check_userevent_name_validation(event_name, app_id) != 0) {
+               free(*sender_id);
+               *sender_id = NULL;
+               return ES_R_ERROR;
+       }
+
+       return ES_R_OK;
 }
 
 static int __eventsystem_check_user_send_validation(const char *event_name)
@@ -1370,13 +1423,24 @@ static int __eventsystem_check_privilege_validation(const char *event_name)
        GVariant *param = NULL;
        GVariant *value = NULL;
        gint result = 0;
+       pid_t pid = getpid();
+       uid_t uid = getuid();
+       char app_id[128] = {0, };
 
        if (!_initialized)
                __initialize();
 
-       if (getuid() < REGULAR_USER)
+       if (uid < REGULAR_USER)
                return ES_R_OK;
 
+       /* This feature is specific to the 'pkgcmd' command.
+                example) TCT is executed in a 5001 user environment, but it cannot have privileges. */
+       ret = aul_app_get_appid_bypid_for_uid(pid, app_id, sizeof(app_id), uid);
+       if (ret == AUL_R_ERROR) {
+               _W("failed to get appid by pid[%d]. Because it is not app, so bypass it", pid);
+               return ES_R_OK;
+       }
+
        if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
                _E("getting gdbus-connetion error");
                ret = ES_R_ERROR;
index 78f386a4c56f0250a8b64b70cb7bcc904212f62d..8496496b812ccf137d8ef4c11c788d753d3f4865 100644 (file)
@@ -3,6 +3,7 @@ PROJECT(eventsystem-unittests C CXX)
 \r
 INCLUDE(FindPkgConfig)\r
 PKG_CHECK_MODULES(eventsystem-unittests REQUIRED\r
+    aul\r
     gmock\r
     dlog\r
     bundle\r
index d81cc974efb3dfbf41a63e28686b1f680230b4db..7025d2c219cb974078546673061e9230376ecbb9 100644 (file)
@@ -19,6 +19,7 @@
 #include <stdio.h>
 #include <glib.h>
 
+#include <aul.h>
 #include <bundle.h>
 
 #include "eventsystem.h"
@@ -36,6 +37,11 @@ extern "C" uid_t getuid() {
   return 5001;
 }
 
+extern "C" int aul_app_get_appid_bypid_for_uid(int pid, char* appid,
+    int len, uid_t uid) {
+  return AUL_R_OK;
+}
+
 class Mocks : public ::testing::NiceMock<GioMock> {};
 
 class EventSystemTest : public TestFixture {