monitor: Add a handler function for REQUEST_SET_RESOURCE_FLAG 72/280372/7
authorSung-hun Kim <sfoon.kim@samsung.com>
Tue, 23 Aug 2022 11:27:56 +0000 (20:27 +0900)
committerSung-hun Kim <sfoon.kim@samsung.com>
Wed, 31 Aug 2022 09:36:54 +0000 (18:36 +0900)
For users of capi, some information such as process information
does not be provided. To distinguish users, we set the visibility
of each resource to PUBLIC or PRIVATE due to the user's context.

When an user sets the visibility of the resource to PUBLIC and
then sets the interest of the resource attribute which has PRIVATE
visibility, the pass daemon will reject it and return -EPERM error.

Change-Id: I23a6b279aa2983aeb6e88cd51458d0c430e8692b
Signed-off-by: Sung-hun Kim <sfoon.kim@samsung.com>
include/monitor/request.h
include/util/resource.h
lib/resource-monitor/resource-monitor.h
src/monitor/request-handler.c
src/util/resource.c

index 1be6279581cb4519d3829489a49df518522f666b..81b95ea1ec42d69f588fe2fa6bcffad32cc6d268 100644 (file)
@@ -47,6 +47,7 @@ enum {
        REQUEST_GET_RESOURCE_TS,
        REQUEST_GET_RESOURCE_LIST_JSON,
        REQUEST_IS_RESOURCE_ATTR_SET,
+       REQUEST_SET_RESOURCE_FLAG,
        REQUEST_MAX,
 };
 
@@ -72,6 +73,7 @@ static const char request_name[][128] = {
        "REQUEST_GET_RESOURCE_TS",
        "REQUEST_GET_RESOURCE_LIST_JSON",
        "REQUEST_IS_RESOURCE_ATTR_SET",
+       "REQUEST_SET_RESOURCE_FLAG",
        "REQUEST_MAX",
 };
 
index cd2deb33e6ba6ad496f1b253ce145a12cb9905d3..028e7c71a4999d6b8fccb6a85c7137234b8f636d 100644 (file)
@@ -154,6 +154,9 @@ void remove_resource_device(struct resource_device *resource_device);
 struct resource *create_resource(int resource_type);
 void delete_resource(struct resource *resource);
 
+/* Set flag of the resource to given flag mask */
+int set_resource_flag(struct resource *resource, u_int64_t flag_mask);
+
 /* Handle resource control */
 int set_resource_control(struct resource *resource, u_int64_t ctrl_id, const void *data);
 const char *get_resource_control_name(struct resource *resource, u_int64_t ctrl_id);
index 84d3e9f9bad60ab8b18da8d4a9e731b5dc8f0f8b..5469c09089a5a9e0ac59ba870efe99c64f860590 100644 (file)
@@ -46,6 +46,12 @@ extern "C" {
 #define RESOURCE_TYPE_NETWORK          11
 #define RESOURCE_TYPE_NONSTANDARD      99
 
+/**
+ * @brief      Resource flags
+ */
+#define RESOURCE_FLAG_PRIVATE          BIT(0)
+#define RESOURCE_FLAG_PUBLIC           BIT(1)
+
 /**
  * @brief      Define the supported attributes according to resource type
  */
index 068d9508f04e8b5b39e1aec3e24dbf939f6a1bf0..7a5db8f73d237792ba248d980c4cdc8bb440c01c 100644 (file)
@@ -261,6 +261,46 @@ static int handle_request_set_resource_attr(struct request_client *client, char
        return ret;
 }
 
+static int handle_request_set_resource_flag(struct request_client *client, char *args)
+{
+       struct resource *res;
+       int resource_id, ret;
+       u_int64_t flag_mask;
+
+       if (!client || !args) {
+               _E("Invalid parameter\n");
+               return -ENOENT;
+       }
+
+       /**
+        * Format of REQUEST_SET_RESOURCE_ATTR and REQUEST_UNSET_RESOURCE_ATTR args:
+        *  - <RESOURCE_ID>
+        */
+       if (sscanf(args, "%d$%"PRIu64, &resource_id, &flag_mask) < 2) {
+               _E("failed to get resource and flag mask, client(%d)\n",
+                                       client->socket_fd);
+               return -EINVAL;
+       }
+
+       res = get_resource_by_id(client, resource_id);
+       if (!res) {
+               _E("failed to get resource, client(%d) | res:name(%s)id(%d)\n",
+                                       client->socket_fd,
+                                       get_resource_name(res), resource_id);
+               return -EINVAL;
+       }
+
+       ret = set_resource_flag(res, flag_mask);
+       if (ret < 0) {
+               _E("failed to set flag to %lx, client(%d) | res:name(%s)id(%d)\n",
+                                       flag_mask, client->socket_fd,
+                                       get_resource_name(res), resource_id);
+               return ret;
+       }
+
+       return 0;
+}
+
 static int handle_request_is_resource_attr_supported(struct request_client *client, char *args, bool *supported)
 {
        struct resource *res;
@@ -763,6 +803,9 @@ static int handle_request(struct request_client *client, char *request)
        case REQUEST_UPDATE_RESOURCE:
                ret = handle_request_update_resource(client, args);
                break;
+       case REQUEST_SET_RESOURCE_FLAG:
+               ret = handle_request_set_resource_flag(client, args);
+               break;
        case REQUEST_GET_RESOURCE_COUNT:
                {
                        int32_t value;
index 411cb4b2525cff2a3e18ebdc68a0e1b9b01cdd23..46a8e040025ef5f75911e3a4777a2e36e433f456 100644 (file)
@@ -25,6 +25,8 @@
 #include <util/resource.h>
 #include <util/log.h>
 
+#include <resource-monitor/resource-monitor.h>
+
 #define RESOURCE_ATTR_MASK                     (ULLONG_MAX)
 #define BIT64_INDEX(id)                                (63 - __builtin_clzll(id))
 #define RESOURCE_ATTR_INDEX(id)                        BIT64_INDEX(id)
@@ -45,6 +47,8 @@ struct resource {
        u_int64_t attr_interest;
        u_int64_t attr_supported;
 
+       u_int64_t flag;
+
        int64_t ts_start;
        int64_t ts_end;
 };
@@ -259,6 +263,7 @@ struct resource *create_resource(int resource_type)
 
        resource->ctrls = driver->ctrls;
        resource->num_ctrls = driver->num_ctrls;
+       resource->flag = RESOURCE_FLAG_PRIVATE;
 
        if (driver->ops.create) {
                ret = driver->ops.create(resource);
@@ -273,6 +278,15 @@ struct resource *create_resource(int resource_type)
        return resource;
 }
 
+int set_resource_flag(struct resource *resource, u_int64_t flag_mask)
+{
+       if (!resource)
+               return -EINVAL;
+
+       resource->flag = flag_mask;
+       return 0;
+}
+
 int set_resource_control(struct resource *resource, u_int64_t ctrl_id, const void *data)
 {
        const struct resource_control *ctrl;
@@ -928,6 +942,23 @@ int get_resource_attr_ptr(struct resource *resource, u_int64_t attr_id, void **d
        return 0;
 }
 
+#define RESOURCE_FLAG_VISIBILITY_MASK          (RESOURCE_FLAG_PRIVATE | RESOURCE_FLAG_PUBLIC)
+#define RESOURCE_ATTR_FLAG_VISIBILITY_MASK     (RESOURCE_ATTR_FLAG_PRIVATE | RESOURCE_ATTR_FLAG_PUBLIC)
+
+static inline bool is_resource_attr_visible(struct resource *resource, const struct resource_attribute *attr)
+{
+       u_int64_t res_visibility, attr_visibility;
+
+       res_visibility = resource->flag & RESOURCE_FLAG_VISIBILITY_MASK;
+       attr_visibility = attr->flag & RESOURCE_ATTR_FLAG_VISIBILITY_MASK;
+
+       /* bigger visibility means smaller privilege */
+       if (res_visibility > attr_visibility)
+               return false;
+
+       return true;
+}
+
 int set_resource_attr_interest(struct resource *resource, u_int64_t interest_mask)
 {
        struct resource_attribute_value *attr_value;
@@ -950,6 +981,13 @@ int set_resource_attr_interest(struct resource *resource, u_int64_t interest_mas
                        goto err;
                }
 
+               if (!is_resource_attr_visible(resource, &resource->attrs[i])) {
+                       _E("res:name(%s) does not have enough privilege to read the attr:name(%s)",
+                                       resource->name, resource->attrs[i].name);
+                       ret = -EPERM;
+                       goto err;
+               }
+
                attr_value = get_resource_attr_value(resource, resource->attrs[i].id);
                if (!attr_value) {
                        _E("failed to get attribute value, res:type(%s) | attr:name(%s)",