common : check SMACK and privilege before running D-Bus signal handler 57/152057/8
authorKichan Kwon <k_c.kwon@samsung.com>
Fri, 15 Sep 2017 10:50:15 +0000 (19:50 +0900)
committerKichan Kwon <k_c.kwon@samsung.com>
Fri, 13 Oct 2017 05:12:12 +0000 (14:12 +0900)
- To block malicious request
  - e.g. Send freezer signal for the app being in foreground
- In addition, modify the privilege for ProcSweep
  - Wearable home app has the code about sending this signal
  - Although it doesn't send currently, but if it send someday,
    we have to control with setting platform privilege

Change-Id: I7f260db24df31679514f00dbeb080e00979f42f9
Signed-off-by: Kichan Kwon <k_c.kwon@samsung.com>
packaging/resourced.spec
resourced.conf
src/CMakeLists.txt
src/common/dbus-handler.c
src/common/dbus-handler.h

index a4858b758d44efa90d9318eff603a0b075d8c755..826c5eff22bd7156238fba59e68cd20c10f3c5ad 100644 (file)
@@ -1,7 +1,7 @@
 Name:       resourced
 Summary:    Resource management daemon
 Version:    0.4
-Release:    10
+Release:    11
 Group:      System/Libraries
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
@@ -46,6 +46,7 @@ BuildRequires:  pkgconfig(capi-system-info)
 BuildRequires:  pkgconfig(libtzplatform-config)
 BuildRequires:  pkgconfig(storage)
 BuildRequires:  pkgconfig(libgum)
+BuildRequires:  pkgconfig(cynara-client)
 
 #only for data types
 BuildRequires:  pkgconfig(tapi)
index 1ffd4de546f80e315d4eaf30dcfc71b5d15e813f..9dea8498ed56df7d55a7c667c58706ee050659f6 100644 (file)
@@ -28,7 +28,7 @@
        <check send_destination="org.tizen.resourced"
                send_interface="org.tizen.resourced.process"
                send_member="ProcSweep"
-               privilege="http://tizen.org/privilege/systemmonitor"/>
+               privilege="http://tizen.org/privilege/systemsettings.admin"/>
        <check send_destination="org.tizen.resourced"
                send_interface="org.tizen.resourced.process"
                send_member="ProcWatchdog"
index 50ca93b619ddd784f844091e4d375ef352bca688..04bda4cec68672acdd60416c9495839303b6b668 100644 (file)
@@ -131,6 +131,7 @@ SET(REQUIRES_LIST ${REQUIRES_LIST}
        storage
        libgum
        libtzplatform-config
+       cynara-client
   )
 
 INCLUDE(FindPkgConfig)
index bcdfc27c70c5a75c4fba8d80b66b7ae569413a41..aa2f4aa67351c692946ea051bce18940a7367e72 100644 (file)
@@ -24,6 +24,7 @@
  *
  */
 
+#include <cynara-client.h>
 #include <glib.h>
 #include <gio/gio.h>
 #include <stdint.h>
@@ -34,6 +35,7 @@
 #include "resourced.h"
 #include "util.h"
 #include "fd-handler.h"
+#include "procfs.h"
 
 #define D_BUS_INIT_RETRY_COUNT 5
 
@@ -107,6 +109,76 @@ static void d_bus_method_handler(GDBusConnection *connection,
 
 static const GDBusInterfaceVTable vtable = { d_bus_method_handler, NULL, NULL };
 
+static gboolean d_bus_is_privileged(const gchar *name)
+{
+       int ret;
+       pid_t pid;
+       uid_t uid;
+       GVariant *reply;
+       cynara *p_cynara;
+       char *session = "";
+       char label[PROC_NAME_MAX];
+       char uid_str[8];
+
+       /* 1. Check SMACK label */
+       reply = g_dbus_connection_call_sync(d_bus_get_connection(),
+                       DBUS_BUS_NAME, DBUS_OBJECT_PATH,
+                       DBUS_INTERFACE_NAME, METHOD_DBUS_GET_PID,
+                       g_variant_new("(s)", name), NULL, G_DBUS_CALL_FLAGS_NONE,
+                       -1, NULL, NULL);
+
+       if (!reply) {
+               _E("Failed to get the PID of sender %s", name);
+               return FALSE;
+       }
+
+       g_variant_get(reply, "(u)", &pid);
+       g_variant_unref(reply);
+
+       ret = proc_get_label(pid, label);
+       if (ret < 0) {
+               _E("Failed to get SMACK label for PID %u (%d)", pid, ret);
+               return FALSE;
+       }
+
+       if (!strncmp(label, "System", 7) || !strncmp(label, "System::Privileged", 19))
+               return TRUE;
+
+       /* 2. Check privilege */
+       reply = g_dbus_connection_call_sync(d_bus_get_connection(),
+                       DBUS_BUS_NAME, DBUS_OBJECT_PATH,
+                       DBUS_INTERFACE_NAME, METHOD_DBUS_GET_UID,
+                       g_variant_new("(s)", name), NULL, G_DBUS_CALL_FLAGS_NONE,
+                       -1, NULL, NULL);
+
+       if (!reply) {
+               _E("Failed to get the UID of sender %s", name);
+               return FALSE;
+       }
+
+       g_variant_get(reply, "(u)", &uid);
+       g_variant_unref(reply);
+
+       snprintf(uid_str, 8, "%u", uid);
+
+       ret = cynara_initialize(&p_cynara, NULL);
+       if (ret != CYNARA_API_SUCCESS) {
+               _E("Failed to initialize cynara (%d)", ret);
+               return FALSE;
+       }
+
+       ret = cynara_check(p_cynara, label, session, uid_str, "http://tizen.org/privilege/systemsettings.admin");
+
+       cynara_finish(p_cynara);
+
+       if (ret != CYNARA_API_ACCESS_ALLOWED) {
+               _E("PID %u doesn't have a privilege", pid);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
 static void d_bus_signal_handler(GDBusConnection *connection,
                const gchar *sender, const gchar *object_path,
                const gchar *interface_name, const gchar *signal_name,
@@ -116,6 +188,11 @@ static void d_bus_signal_handler(GDBusConnection *connection,
        if (!signal || !signal->callback)
                return;
 
+       if (!d_bus_is_privileged(sender)) {
+               _E("This sender doesn't have privilege to run %s", signal_name);
+               return;
+       }
+
        signal->callback(parameters);
 }
 
index 36fd8bad0d36cda153cbda904547027de7a5ea45..0af7cc860d1deaca0c1e8e44403d0057420d68ff 100644 (file)
@@ -217,6 +217,16 @@ struct d_bus_signal {
 #define SIGNAL_AMD_TERMINATED  "AppTerminated"
 #define SIGNAL_AMD_SUSPNED     "SuspendHint"
 
+/*
+ * D-Bus daemon
+ */
+#define DBUS_BUS_NAME        "org.freedesktop.DBus"
+#define DBUS_OBJECT_PATH     "/org/freedesktop/DBus"
+#define DBUS_INTERFACE_NAME  DBUS_BUS_NAME
+
+#define METHOD_DBUS_GET_PID         "GetConnectionUnixProcessID"
+#define METHOD_DBUS_GET_UID         "GetConnectionUnixUser"
+
 struct dbus_byte {
        char *data;
        int size;