qos manager鉴权方式切换

Signed-off-by: yaowenrui <yaowenrui2@huawei.com>
This commit is contained in:
yaowenrui
2023-11-07 15:00:10 +08:00
parent 2099969b4e
commit c72fc46db7
4 changed files with 94 additions and 77 deletions
+62 -42
View File
@@ -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;
}
init_authority_record(&auth_super);
change_to_super(&auth_super);
static int init_super_authority(unsigned int auth_tgid)
{
int ret;
struct auth_struct *auth_super;
ret = idr_alloc(ua_idr, &auth_super, SUPER_UID, SUPER_UID + 1, GFP_ATOMIC);
if (ret != SUPER_UID) {
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, 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();
+2 -2
View File
@@ -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,
+27 -30
View File
@@ -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
+3 -3
View File
@@ -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,