From 5907f4839f9312320e2210b870bdee5bb9e8b91c Mon Sep 17 00:00:00 2001 From: Jiwoong Im Date: Fri, 14 Oct 2016 15:44:39 +0900 Subject: [PATCH] Add buxton_update_client_label api - Because candidate app has "User" label, buxton2d should update buxton client label after candidate app changes smack label. To solve this, buxton2 provide api to update app's client label. Change-Id: I57820f6d83197bc8059dd7b1e5d41007a313045f Signed-off-by: Jiwoong Im --- daemon/daemon.c | 41 +++++++++++++++++++--- lib/buxton2.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/include/buxton2.h | 19 ++++++++++ 3 files changed, 151 insertions(+), 5 deletions(-) diff --git a/daemon/daemon.c b/daemon/daemon.c index 09aeb88..c7a212d 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -503,6 +503,35 @@ static void proc_get_priv(struct bxt_client *cli, resp->val = val; } +static int update_label(struct bxt_client *cli) +{ + int fd; + int ret; + char buf[1024]; + char path[1024]; + + snprintf(path, sizeof(path), "/proc/%d/attr/current", cli->cred.pid); + fd = open(path, O_RDONLY); + if (fd < 0) + return -1; + + ret = read(fd, buf, sizeof(buf) - 1); + if (ret <= 0) { + close(fd); + return -1; + } else { + buf[ret] = 0; + } + + close(fd); + + if (cli->label) + free(cli->label); + cli->label = strdup(buf); + + return 0; +} + static void proc_control(struct bxt_client *cli, struct request *rqst, struct response *resp) { @@ -510,18 +539,20 @@ static void proc_control(struct bxt_client *cli, assert(rqst); assert(resp); - if (cli->cred.uid != 0) { - resp->res = EPERM; - return; - } - if (!strcmp(rqst->key, "set_security_mode")) { + if (cli->cred.uid != 0) { + resp->res = EPERM; + return; + } if (rqst->val->value.b == TRUE) buxton_cynara_enable(); else buxton_cynara_disable(); resp->res = 0; return; + } else if (!strcmp(rqst->key, "update_client_label")) { + resp->res = update_label(cli); + return; } resp->res = ENOTSUP; } diff --git a/lib/buxton2.c b/lib/buxton2.c index 1638018..708052f 100644 --- a/lib/buxton2.c +++ b/lib/buxton2.c @@ -2180,6 +2180,102 @@ EXPORT int buxton_disable_security_sync(struct buxton_client *client) return 0; } +static void update_label_sync_cb(int status, const struct buxton_layer *layer, + const char *key, const struct buxton_value *val, + void *user_data) +{ + struct response *resp = user_data; + + assert(resp); + + resp->res = status; +} + +static struct bxt_req *update_client_label(struct buxton_client *client, + buxton_response_callback callback, + void *user_data) +{ + int r; + struct bxt_req *req; + struct request rqst; + struct buxton_layer *layer; + + layer = layer_create("dummy"); + + req = create_req(layer, NULL, callback, NULL, user_data); + + if (!req) + return NULL; + layer_unref(layer); + + memset(&rqst, 0, sizeof(rqst)); + rqst.type = MSG_CTRL; + rqst.msgid = req->msgid; + rqst.layer = req->layer; + rqst.key = strdup("update_client_label"); + + pthread_mutex_lock(&client->lock); + g_hash_table_insert(client->req_cbs, GUINT_TO_POINTER(req->msgid), req); + + r = send_req(client, &rqst); + + free(rqst.key); + if (r == -1) { + g_hash_table_remove(client->req_cbs, + GUINT_TO_POINTER(req->msgid)); + pthread_mutex_unlock(&client->lock); + return NULL; + } + + pthread_mutex_unlock(&client->lock); + return req; +} + +EXPORT int buxton_update_client_label(struct buxton_client *client, + buxton_response_callback callback, void *user_data) +{ + struct bxt_req *req; + + pthread_mutex_lock(&clients_lock); + req = update_client_label(client, callback, user_data); + if (!req) { + pthread_mutex_unlock(&clients_lock); + return -1; + } + + pthread_mutex_unlock(&clients_lock); + return 0; +} + +EXPORT int buxton_update_client_label_sync(struct buxton_client *client) +{ + int r; + struct bxt_req *req; + struct response resp; + + pthread_mutex_lock(&clients_lock); + req = update_client_label(client, update_label_sync_cb, &resp); + if (!req) { + pthread_mutex_unlock(&clients_lock); + return -1; + } + + r = wait_msg(client, req->msgid); + if (r == -1) { + pthread_mutex_unlock(&clients_lock); + return -1; + } + + if (resp.res) { + errno = resp.res; + pthread_mutex_unlock(&clients_lock); + return -1; + } + + pthread_mutex_unlock(&clients_lock); + return 0; +} + static void free_noti(struct bxt_noti *noti) { if (!noti) diff --git a/lib/include/buxton2.h b/lib/include/buxton2.h index 512e9c1..aec394a 100644 --- a/lib/include/buxton2.h +++ b/lib/include/buxton2.h @@ -778,6 +778,25 @@ int buxton_disable_security(struct buxton_client *client, */ int buxton_disable_security_sync(struct buxton_client *client); +/** + * Update client's label + * + * @param[in] client #buxton_client struct + * @param[in] callback response callback function + * @param[in] user_data User data to be used with callback function + * @return 0 on success, -1 on error(when an error occurred, errno is set) + */ +int buxton_update_client_label(struct buxton_client *client, + buxton_response_callback callback, void *user_data); + +/** + * Update client's label synchronously + * + * @param[in] client #buxton_client struct + * @return 0 on success, -1 on error(when an error occurred, errno is set) + */ +int buxton_update_client_label_sync(struct buxton_client *client); + #ifdef __cplusplus } #endif -- 2.7.4