From 5081911ad619e90cf0c1734125b1475698d017f3 Mon Sep 17 00:00:00 2001 From: Sung-hun Kim Date: Tue, 23 Aug 2022 20:27:56 +0900 Subject: [PATCH] monitor: Add a handler function for REQUEST_SET_RESOURCE_FLAG 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 --- include/monitor/request.h | 2 ++ include/util/resource.h | 3 +++ lib/resource-monitor/resource-monitor.h | 6 +++++ src/monitor/request-handler.c | 43 +++++++++++++++++++++++++++++++++ src/util/resource.c | 38 +++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+) diff --git a/include/monitor/request.h b/include/monitor/request.h index 1be6279..81b95ea 100644 --- a/include/monitor/request.h +++ b/include/monitor/request.h @@ -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", }; diff --git a/include/util/resource.h b/include/util/resource.h index cd2deb3..028e7c7 100644 --- a/include/util/resource.h +++ b/include/util/resource.h @@ -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); diff --git a/lib/resource-monitor/resource-monitor.h b/lib/resource-monitor/resource-monitor.h index 84d3e9f..5469c09 100644 --- a/lib/resource-monitor/resource-monitor.h +++ b/lib/resource-monitor/resource-monitor.h @@ -47,6 +47,12 @@ extern "C" { #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 */ diff --git a/src/monitor/request-handler.c b/src/monitor/request-handler.c index 068d950..7a5db8f 100644 --- a/src/monitor/request-handler.c +++ b/src/monitor/request-handler.c @@ -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: + * - + */ + 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; diff --git a/src/util/resource.c b/src/util/resource.c index 411cb4b..46a8e04 100644 --- a/src/util/resource.c +++ b/src/util/resource.c @@ -25,6 +25,8 @@ #include #include +#include + #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)", -- 2.7.4