power: add privilege check routine for reboot operation 30/92130/7 accepted/tizen/common/20161020.043515 submit/tizen/20161020.031059
authortaeyoung <ty317.kim@samsung.com>
Thu, 13 Oct 2016 09:47:26 +0000 (18:47 +0900)
committertaeyoung <ty317.kim@samsung.com>
Wed, 19 Oct 2016 09:36:35 +0000 (18:36 +0900)
The reboot operation is permitted to privileged apps only.

Change-Id: I58e161cbb7b6b1bb54fc6e7dffd5f62eefa12fec
Signed-off-by: taeyoung <ty317.kim@samsung.com>
src/core/common.c
src/core/common.h
src/power/power-handler.c
src/tzip/tzip.c

index 209fea5..3cb598f 100644 (file)
@@ -41,6 +41,8 @@
 #define VIP_DIR         "/tmp/vip"
 #define BUFF_MAX        255
 
+#define APP_ATTR_PATH "/proc/%d/attr/current"
+
 /**
  * Opens "/proc/$pid/oom_score_adj" file for w/r;
  * Return: FILE pointer or NULL
@@ -382,3 +384,27 @@ void print_time(const char *prefix)
                _D("%s --> %d:%02d:%02d %d",
                                prefix, tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec);
 }
+
+int get_privilege(pid_t pid, char *name, size_t len)
+{
+       char path[PATH_MAX];
+       char attr[BUFF_MAX];
+       size_t attr_len;
+       FILE *fp;
+
+       snprintf(path, sizeof(path), APP_ATTR_PATH, pid);
+
+       fp = fopen(path, "r");
+       if (!fp)
+               return -errno;
+
+       attr_len = fread(attr, 1, sizeof(attr) - 1, fp);
+       fclose(fp);
+       if (attr_len == 0)
+               return -ENOENT;
+
+       attr[attr_len] = '\0';
+
+       snprintf(name, len, "%s", attr);
+       return 0;
+}
index 027a233..71fde42 100644 (file)
@@ -146,6 +146,7 @@ int sys_set_str(char *fname, char *val);
 int terminate_process(const char *partition, bool force);
 int mount_check(const char* path);
 void print_time(const char *prefix);
+int get_privilege(pid_t pid, char *name, size_t len);
 
 #endif /* __CORE_COMMON_H__ */
 
index 264d8fc..a8dda68 100644 (file)
@@ -90,6 +90,29 @@ static int telephony_exit(void *data)
        return ret;
 }
 
+static int app_privileged(pid_t pid)
+{
+       char attr[64];
+       int ret;
+       size_t len;
+
+       ret = get_privilege(pid, attr, sizeof(attr));
+       if (ret < 0) {
+               _E("Failed to get privilege of PID(%d)", pid);
+               return 0;
+       }
+
+       len = strlen(attr);
+
+       if (!strncmp("System::Privileged", attr, len + 1))
+               return 1;
+
+       if (strstr(attr, "User::Pkg::") == attr)
+               return 1;
+
+       return 0;
+}
+
 static void poweroff_stop_systemd_service(void)
 {
        _D("systemd service stop");
@@ -394,7 +417,7 @@ static void poweroff_idler_cb(void *data)
                update_pm_setting(SETTING_POWEROFF, val);
 }
 
-static int power_execute(void *data)
+static int power_execute_pid(void *data, pid_t pid)
 {
        int ret;
        long val;
@@ -409,9 +432,13 @@ static int power_execute(void *data)
                val = POWER_OFF_DIRECT;
        else if (strncmp(PWROFF_POPUP, str, PWROFF_POPUP_LEN) == 0)
                val = POWER_OFF_POPUP;
-       else if (strncmp(POWER_REBOOT, str, POWER_REBOOT_LEN) == 0)
+       else if (strncmp(POWER_REBOOT, str, POWER_REBOOT_LEN) == 0) {
+               if (!app_privileged(pid)) {
+                       _E("PID(%d) does not have the permission for reboot", pid);
+                       return -EPERM;
+               }
                val = POWER_OFF_RESTART;
-       else {
+       else {
                _E("Invalid parameter : data(%s)", str);
                return -EINVAL;
        }
@@ -425,6 +452,11 @@ static int power_execute(void *data)
        return 0;
 }
 
+static int power_execute(void *data)
+{
+       return power_execute_pid(data, getpid());
+}
+
 static DBusMessage *dbus_power_handler(E_DBus_Object *obj, DBusMessage *msg)
 {
        DBusError err;
@@ -458,7 +490,8 @@ static DBusMessage *dbus_power_handler(E_DBus_Object *obj, DBusMessage *msg)
                goto out;
        }
 
-       ret = power_execute(type_str);
+       _I("PID(%d) requests %s", pid, type_str);
+       ret = power_execute_pid(type_str, pid);
 
 out:
        reply = dbus_message_new_method_return(msg);
@@ -474,6 +507,7 @@ static DBusMessage *request_reboot(E_DBus_Object *obj, DBusMessage *msg)
        DBusMessage *reply;
        char *str;
        int ret;
+       pid_t pid;
 
        if (!dbus_message_get_args(msg, NULL,
                    DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID)) {
@@ -482,8 +516,10 @@ static DBusMessage *request_reboot(E_DBus_Object *obj, DBusMessage *msg)
                goto out;
        }
 
-       _I("reboot command : %s", str);
-       ret = power_execute(POWER_REBOOT);
+       pid = get_edbus_sender_pid(msg);
+
+       _I("PID(%d) requests reboot with command : %s", pid, str);
+       ret = power_execute_pid(POWER_REBOOT, pid);
 
 out:
        reply = dbus_message_new_method_return(msg);
index aff62f6..c005766 100644 (file)
@@ -23,6 +23,7 @@
 #include "core/edbus-handler.h"
 #include "core/list.h"
 #include "core/device-notifier.h"
+#include "core/common.h"
 
 #include <fuse.h>
 #include <stdio.h>
@@ -43,7 +44,6 @@
 #include "tzip.h"
 #include "tzip-utility.h"
 
-#define APP_ATTR_PATH "/proc/%d/attr/current"
 
 static pthread_t thread;
 static pthread_t mount_thread;
@@ -54,31 +54,25 @@ static GAsyncQueue *async_queue;
 
 static int check_smack_label(pid_t pid)
 {
-       char path[PATH_MAX];
        char attr[64];
        size_t len;
-       FILE *fp;
-
-       snprintf(path, sizeof(path), APP_ATTR_PATH, pid);
-
-       fp = fopen(path, "r");
-       if (!fp)
-               return 0;
+       int ret;
 
-       len = fread(attr, 1, sizeof(attr) - 1, fp);
-       fclose(fp);
-       if (len == 0)
+       ret = get_privilege(pid, attr, sizeof(attr));
+       if (ret < 0) {
+               _E("Failed to get privilege of PID(%d)", pid);
                return 0;
+       }
 
-       attr[len] = '\0';
+       len = strlen(attr) + 1;
 
-       if (!strncmp("System", attr, len + 1))
+       if (!strncmp("System", attr, len))
                return 1;
 
-       if (!strncmp("User", attr, len + 1))
+       if (!strncmp("User", attr, len))
                return 1;
 
-       if (!strncmp("System::Privileged", attr, len + 1))
+       if (!strncmp("System::Privileged", attr, len))
                return 1;
 
        return 0;