diff --git a/qos_auth/auth_ctl/auth_ctrl.c b/qos_auth/auth_ctl/auth_ctrl.c index 8a4ec79fdfa5943994446f042d093ee37bbb13b1..aae7a2c66f4f5c64c730606815acc2665fc3aeae 100644 --- a/qos_auth/auth_ctl/auth_ctrl.c +++ b/qos_auth/auth_ctl/auth_ctrl.c @@ -53,8 +53,6 @@ struct mutex *get_auth_idr_mutex(void) return &ua_idr_mutex; } -static struct auth_struct auth_super; - /* * change auth's status to SYSTEM and enable all feature access */ @@ -116,10 +114,8 @@ void put_auth_struct(struct auth_struct *auth) __put_auth_struct(auth); } -static int init_authority_control(void) +static int init_ua_idr(void) { - int ret; - ua_idr = kzalloc(sizeof(*ua_idr), GFP_ATOMIC); if (ua_idr == NULL) { pr_err("[AUTH_CTRL] auth idr init failed, no memory!\n"); @@ -127,23 +123,31 @@ static int init_authority_control(void) } idr_init(ua_idr); + + return 0; +} + +static int init_super_authority(unsigned int auth_tgid) +{ + int ret; + struct auth_struct *auth_super; - init_authority_record(&auth_super); - change_to_super(&auth_super); + auth_super = kzalloc(sizeof(*auth_super), GFP_ATOMIC); + if(auth_super == NULL) { + pr_err("[AUTH_CTRL] auth struct alloc failed\n"); + return -ENOMEM; + } + init_authority_record(auth_super); + change_to_super(auth_super); - ret = idr_alloc(ua_idr, &auth_super, SUPER_UID, SUPER_UID + 1, GFP_ATOMIC); - if (ret != SUPER_UID) { + ret = idr_alloc(ua_idr, auth_super, auth_tgid, auth_tgid + 1, GFP_ATOMIC); + if(ret != auth_tgid) { pr_err("[AUTH_CTRL] authority for super init failed! ret=%d\n", ret); - goto err; + kfree(auth_super); + return ret; } return 0; - -err: - idr_destroy(ua_idr); - kfree(ua_idr); - - return ret; } int authority_remove_handler(int id, void *p, void *para) @@ -197,12 +201,12 @@ static inline void set_auth_flag(struct auth_ctrl_data *data, struct auth_struct static int auth_enable(struct auth_ctrl_data *data) { struct auth_struct *auth_to_enable; - unsigned int uid = data->uid; + unsigned int tgid = data->pid; int status = data->status; int ret; mutex_lock(&ua_idr_mutex); - auth_to_enable = idr_find(ua_idr, uid); + auth_to_enable = idr_find(ua_idr, tgid); /* auth exist, just resume the task's qos request */ if (auth_to_enable) { get_auth_struct(auth_to_enable); @@ -241,7 +245,7 @@ static int auth_enable(struct auth_ctrl_data *data) set_auth_flag(data, auth_to_enable); auth_to_enable->status = status; - ret = idr_alloc(ua_idr, auth_to_enable, uid, uid + 1, GFP_ATOMIC); + ret = idr_alloc(ua_idr, auth_to_enable, tgid, tgid + 1, GFP_ATOMIC); if (ret < 0) { pr_err("[AUTH_CTRL] add auth to idr failed, no memory!\n"); kfree(auth_to_enable); @@ -256,14 +260,14 @@ out: static int auth_delete(struct auth_ctrl_data *data) { struct auth_struct *auth_to_delete; - unsigned int uid = data->uid; + unsigned int tgid = data->pid; mutex_lock(&ua_idr_mutex); - auth_to_delete = (struct auth_struct *)idr_remove(ua_idr, uid); + auth_to_delete = (struct auth_struct *)idr_remove(ua_idr, tgid); if (!auth_to_delete) { mutex_unlock(&ua_idr_mutex); - pr_err("[AUTH_CTRL] no auth data for this uid=%d, delete failed\n", uid); - return -UID_NOT_FOUND; + pr_err("[AUTH_CTRL] no auth data for this pid=%d, delete failed\n", tgid); + return -PID_NOT_FOUND; } mutex_unlock(&ua_idr_mutex); @@ -282,14 +286,14 @@ static int auth_delete(struct auth_ctrl_data *data) static int auth_get(struct auth_ctrl_data *data) { struct auth_struct *auth_to_get; - unsigned int uid = data->uid; + unsigned int tgid = data->pid; mutex_lock(&ua_idr_mutex); - auth_to_get = idr_find(ua_idr, uid); + auth_to_get = idr_find(ua_idr, tgid); if (!auth_to_get) { mutex_unlock(&ua_idr_mutex); - pr_err("[AUTH_CTRL] no auth data for this uid=%d to get\n", uid); - return -UID_NOT_FOUND; + pr_err("[AUTH_CTRL] no auth data for this pid=%d to get\n", tgid); + return -PID_NOT_FOUND; } get_auth_struct(auth_to_get); mutex_unlock(&ua_idr_mutex); @@ -317,7 +321,7 @@ static int auth_get(struct auth_ctrl_data *data) static int auth_switch(struct auth_ctrl_data *data) { struct auth_struct *auth; - unsigned int uid = data->uid; + unsigned int tgid = data->pid; unsigned int status = data->status; if (status == 0 || status >= AUTH_STATUS_MAX_NR) { @@ -326,11 +330,11 @@ static int auth_switch(struct auth_ctrl_data *data) } mutex_lock(&ua_idr_mutex); - auth = idr_find(ua_idr, uid); + auth = idr_find(ua_idr, tgid); if (!auth) { mutex_unlock(&ua_idr_mutex); - pr_err("[AUTH_CTRL] no auth data for this uid to switch=%d\n", uid); - return -UID_NOT_FOUND; + pr_err("[AUTH_CTRL] no auth data for this pid=%d to switch\n", tgid); + return -PID_NOT_FOUND; } get_auth_struct(auth); mutex_unlock(&ua_idr_mutex); @@ -358,10 +362,10 @@ typedef int (*auth_manipulate_func)(struct auth_ctrl_data *data); static auth_manipulate_func auth_func_array[AUTH_MAX_NR] = { /* - * auth_enable: Start authority control for specific uid. + * auth_enable: Start authority control for specific tgid. * auth_delte: End authroity control, remove statistic datas. * auth_get: Get auth info, deprecated. - * auth_switch: Change authority flag and status for specific uid. + * auth_switch: Change authority flag and status for specific tgid. */ NULL, auth_enable, @@ -523,6 +527,7 @@ bool check_authorized(unsigned int func_id, unsigned int type) struct auth_struct *auth; unsigned int af = get_authority_flag(func_id); unsigned int uid = get_authority_uid(NULL); + unsigned int tgid = task_tgid_nr(current); mutex_lock(&ua_idr_mutex); if (!ua_idr) { @@ -531,19 +536,31 @@ bool check_authorized(unsigned int func_id, unsigned int type) return authorized; } - auth = (struct auth_struct *)idr_find(ua_idr, uid); + auth = (struct auth_struct *)idr_find(ua_idr, tgid); if (!auth) { - mutex_unlock(&ua_idr_mutex); - pr_err("[AUTH_CTRL] no auth data for this uid=%d\n", uid); - return authorized; + if (uid != SUPER_UID) { + mutex_unlock(&ua_idr_mutex); + pr_err("[AUTH_CTRL] no auth data for this pid = %d\n, tgid"); + return authorized; + } else if (init_super_authority(tgid)) { + mutex_unlock(&ua_idr_mutex); + pr_err("[AUTH_CTRL] init super authority failed\n"); + return authorized; + } + + //the auth must exist + auth = (struct auth_struct *)idr_find(ua_idr, tgid); + if (!auth) + return authorized; } + get_auth_struct(auth); mutex_unlock(&ua_idr_mutex); mutex_lock(&auth->mutex); if (auth->status == AUTH_STATUS_DEAD) { mutex_unlock(&auth->mutex); - pr_info("[AUTH_CTRL] not valied auth for uid %d\n", uid); + pr_info("[AUTH_CTRL] not valid auth for pid %d\n", tgid); put_auth_struct(auth); return authorized; } @@ -560,18 +577,21 @@ bool check_authorized(unsigned int func_id, unsigned int type) /* * Return authority info for given task * return current's auth if p is NULL - * recount will inc if this call return the valid auth + * refcount will inc if this call return the valid auth * make sure to call put_auth_struct before the calling end */ struct auth_struct *get_authority(struct task_struct *p) { - unsigned int uid = get_authority_uid(p); + unsigned int tgid; struct auth_struct *auth; + tgid = (p == NULL ? current->tgid : p->tgid); + mutex_lock(&ua_idr_mutex); - auth = idr_find(ua_idr, uid); + auth = idr_find(ua_idr, tgid); if (auth) get_auth_struct(auth); + mutex_unlock(&ua_idr_mutex); return auth; @@ -616,7 +636,7 @@ static __init int auth_ctrl_init_module(void) pr_info("auth_ctrl init success\n"); - BUG_ON(init_authority_control()); + BUG_ON(init_ua_idr()); #ifdef CONFIG_QOS_CTRL init_qos_ctrl(); diff --git a/qos_auth/auth_ctl/auth_qos_debug.c b/qos_auth/auth_ctl/auth_qos_debug.c index a627ce47298ffe4ca50118981d51035a363b2cc4..b140b50ea7bf287f8abed328bb1d11e5768d6543 100644 --- a/qos_auth/auth_ctl/auth_qos_debug.c +++ b/qos_auth/auth_ctl/auth_qos_debug.c @@ -33,9 +33,9 @@ do { \ } while (0) static void print_auth_id(struct seq_file *file, - const int uid) + const int tgid) { - seq_printf_auth(file, "AUTH_ID :%d\n", uid); + seq_printf_auth(file, "AUTH_PID :%d\n", tgid); } static void print_auth_info(struct seq_file *file, diff --git a/qos_auth/auth_ctl/qos_ctrl.c b/qos_auth/auth_ctl/qos_ctrl.c index 920f90f96b5dd8b2271e9f8c31455e679d59ddc4..999c5fa1c1f259e0bd2bcd7e1229dddb7dd174f8 100644 --- a/qos_auth/auth_ctl/qos_ctrl.c +++ b/qos_auth/auth_ctl/qos_ctrl.c @@ -23,6 +23,8 @@ typedef long (*qos_ctrl_func)(int abi, void __user *uarg); static long ctrl_qos_operation(int abi, void __user *uarg); static long ctrl_qos_policy(int abi, void __user *uarg); +#define QOS_LEVEL_SET_MAX 5 + static qos_ctrl_func g_func_array[QOS_CTRL_MAX_NR] = { NULL, /* reserved */ ctrl_qos_operation, @@ -176,23 +178,21 @@ static int qos_remove_task(struct task_struct *p) return 0; } -static inline bool same_uid(struct task_struct *dude, struct task_struct *bro) -{ - return uid_eq(task_uid(dude), task_uid(bro)); -} - static inline bool super_user(struct task_struct *p) { return super_uid(task_uid(p).val); } /* - * judge permission for changing other tasks' qos + * judge permission for changing tasks' qos */ -static bool can_change_qos(struct task_struct *p) +static bool can_change_qos(struct task_struct *p, unsigned int qos_level) { - if (p != current && !same_uid(current, p) && !super_user(current)) { - pr_err("[QOS_CTRL] %d apply for others not permit\n", p->pid); + struct auth_struct *auth; + auth = get_authority(p); + /* just system & root user can set(be setted) high qos level */ + if (!auth || (auth && !super_user(p) && qos_level > QOS_LEVEL_SET_MAX)) { + pr_err("[QOS_CTRL] %d have no permission to change qos\n", p->pid); return false; } @@ -227,19 +227,18 @@ int qos_apply(struct qos_ctrl_data *data) goto out_put_task; } - if (!can_change_qos(p)) { - pr_err("[QOS_CTRL] apply for others not permit\n"); + if (!can_change_qos(current, level)) { + pr_err("[QOS_CTRL] QOS apply not permit\n"); ret = -ARG_INVALID; goto out_put_task; } auth = get_authority(p); if (!auth) { - pr_err("[QOS_CTRL] no auth data for pid=%d(%s) this uid=%d, qos apply failed\n", - p->pid, p->comm, p->cred->uid.val); - put_task_struct(p); - ret = -UID_NOT_FOUND; - goto out; + pr_err("[QOS_CTRL] no auth data for pid=%d(%s), qos apply failed\n", + p->tgid, p->comm); + ret = -PID_NOT_FOUND; + goto out_put_task; } mutex_lock(&auth->mutex); @@ -315,19 +314,12 @@ int qos_leave(struct qos_ctrl_data *data) goto out_put_task; } - if (!can_change_qos(p)) { - pr_err("[QOS_CTRL] apply for others not permit\n"); - ret = -ARG_INVALID; - goto out_put_task; - } - auth = get_authority(p); if (!auth) { - pr_err("[QOS_CTRL] no auth data for pid=%d(%s) this uid=%d, qos stop failed\n", - p->pid, p->comm, p->cred->uid.val); - put_task_struct(p); - ret = -UID_NOT_FOUND; - goto out; + pr_err("[QOS_CTRL] no auth data for pid=%d(%s), qos stop failed\n", + p->tgid, p->comm); + ret = -PID_NOT_FOUND; + goto out_put_task; } mutex_lock(&auth->mutex); @@ -335,13 +327,18 @@ int qos_leave(struct qos_ctrl_data *data) qts = (struct qos_task_struct *) &p->qts; level = qts->in_qos; - if (level == NO_QOS) { pr_err("[QOS_CTRL] task not in qos list, qos stop failed\n"); ret = -ARG_INVALID; goto out_unlock; } + if (!can_change_qos(current, 0)) { + pr_err("[QOS_CTRL] apply for others not permit\n"); + ret = -ARG_INVALID; + goto out_unlock; + } + if (auth->status == AUTH_STATUS_DEAD) { pr_err("[QOS_CTRL] this auth data has been deleted\n"); ret = -INVALID_AUTH; @@ -671,8 +668,8 @@ long do_qos_ctrl_ioctl(int abi, struct file *file, unsigned int cmd, unsigned lo #ifdef CONFIG_QOS_AUTHORITY if (!check_authorized(func_cmd, QOS_AUTH_FLAG)) { - pr_err("[QOS_CTRL] %s: uid not authorized\n", __func__); - return -UID_NOT_AUTHORIZED; + pr_err("[QOS_CTRL] %s: pid not authorized\n", __func__); + return -PID_NOT_AUTHORIZED; } #endif diff --git a/qos_auth/include/auth_ctrl.h b/qos_auth/include/auth_ctrl.h index d359e63bbc1a4f06ed3a1bf00cb6d0db0652813a..3fa0be5586e768e4ca9d32631be970bad509378a 100644 --- a/qos_auth/include/auth_ctrl.h +++ b/qos_auth/include/auth_ctrl.h @@ -43,7 +43,7 @@ enum auth_flag_type { #define INVALIED_AUTH_FLAG 0x00000000 struct auth_ctrl_data { - unsigned int uid; + unsigned int pid; /* * type: operation type, see auth_manipulate_type, valid range [1, AUTH_MAX_NR) @@ -66,8 +66,8 @@ enum auth_err_no { ARG_INVALID = 1, THREAD_EXITING, DIRTY_QOS_POLICY, - UID_NOT_AUTHORIZED, - UID_NOT_FOUND, + PID_NOT_AUTHORIZED, + PID_NOT_FOUND, PID_DUPLICATE, PID_NOT_EXIST, INVALID_AUTH,