1// SPDX-License-Identifier: GPL-2.0 2/* 3 * drivers/auth_ctl/auth_ctrl.c 4 * 5 * Copyright (c) 2022 Huawei Device Co., Ltd. 6 * 7 */ 8 9#include <linux/cred.h> 10#include <linux/mutex.h> 11#include <linux/errno.h> 12#include <linux/fs.h> 13#include <linux/miscdevice.h> 14#include <linux/module.h> 15#include <linux/sched.h> 16#include <linux/kernel.h> 17#include <linux/slab.h> 18#include <linux/proc_fs.h> 19#include <linux/seq_file.h> 20#include <linux/sched/auth_ctrl.h> 21#include <linux/sched/rtg_auth.h> 22#include <linux/sched/qos_ctrl.h> 23#include <linux/sched/qos_auth.h> 24 25#include "auth_ctrl.h" 26#ifdef CONFIG_QOS_CTRL 27#include "qos_ctrl.h" 28#endif 29 30typedef long (*auth_ctrl_func)(int abi, void __user *arg); 31 32static long ctrl_auth_basic_operation(int abi, void __user *uarg); 33 34static auth_ctrl_func g_func_array[AUTH_CTRL_MAX_NR] = { 35 NULL, /* reserved */ 36 ctrl_auth_basic_operation, 37}; 38 39/* 40 * uid-based authority idr table 41 */ 42static struct idr *ua_idr; 43 44struct idr *get_auth_ctrl_idr(void) 45{ 46 return ua_idr; 47} 48 49static DEFINE_MUTEX(ua_idr_mutex); 50 51struct mutex *get_auth_idr_mutex(void) 52{ 53 return &ua_idr_mutex; 54} 55 56/* 57 * change auth's status to SYSTEM and enable all feature access 58 */ 59static void change_to_super(struct auth_struct *auth) 60{ 61#ifdef CONFIG_RTG_AUTHORITY 62 auth->rtg_auth_flag = AF_RTG_ALL; 63#endif 64#ifdef CONFIG_QOS_AUTHORITY 65 auth->qos_auth_flag = AF_QOS_ALL; 66#endif 67 auth->status = AUTH_STATUS_SYSTEM_SERVER; 68} 69 70static void init_authority_record(struct auth_struct *auth) 71{ 72#ifdef CONFIG_QOS_AUTHORITY 73 int i; 74#endif 75 76#ifdef CONFIG_RTG_AUTHORITY 77 auth->rtg_auth_flag = 0; 78#endif 79#ifdef CONFIG_QOS_AUTHORITY 80 auth->qos_auth_flag = 0; 81#endif 82 auth->status = AUTH_STATUS_DISABLED; 83 mutex_init(&auth->mutex); 84 refcount_set(&auth->usage, 1); 85#ifdef CONFIG_QOS_CTRL 86 for (i = QOS_POLICY_MIN_LEVEL; i < NR_QOS; ++i) { 87 INIT_LIST_HEAD(&auth->tasks[i]); 88 auth->num[i] = 0; 89 } 90#endif 91} 92 93void get_auth_struct(struct auth_struct *auth) 94{ 95 refcount_inc(&auth->usage); 96} 97 98static void __put_auth_struct(struct auth_struct *auth) 99 100{ 101 WARN_ON(auth->status != AUTH_STATUS_DEAD); 102 WARN_ON(refcount_read(&auth->usage)); 103 104#ifdef CONFIG_QOS_CTRL 105 /* refcount is zero here, no contend, no lock. */ 106 remove_qos_tasks(auth); 107#endif 108 kfree(auth); 109} 110 111void put_auth_struct(struct auth_struct *auth) 112{ 113 if (refcount_dec_and_test(&auth->usage)) 114 __put_auth_struct(auth); 115} 116 117static int init_ua_idr(void) 118{ 119 ua_idr = kzalloc(sizeof(*ua_idr), GFP_ATOMIC); 120 if (ua_idr == NULL) { 121 pr_err("[AUTH_CTRL] auth idr init failed, no memory!\n"); 122 return -ENOMEM; 123 } 124 125 idr_init(ua_idr); 126 127 return 0; 128} 129 130static int init_super_authority(unsigned int auth_tgid) 131{ 132 int ret; 133 struct auth_struct *auth_super; 134 135 auth_super = kzalloc(sizeof(*auth_super), GFP_ATOMIC); 136 if(auth_super == NULL) { 137 pr_err("[AUTH_CTRL] auth struct alloc failed\n"); 138 return -ENOMEM; 139 } 140 init_authority_record(auth_super); 141 change_to_super(auth_super); 142 143 ret = idr_alloc(ua_idr, auth_super, auth_tgid, auth_tgid + 1, GFP_ATOMIC); 144 if(ret != auth_tgid) { 145 pr_err("[AUTH_CTRL] authority for super init failed! ret=%d\n", ret); 146 kfree(auth_super); 147 return ret; 148 } 149 150 return 0; 151} 152 153int authority_remove_handler(int id, void *p, void *para) 154{ 155 struct auth_struct *auth = (struct auth_struct *)p; 156 157 mutex_lock(&auth->mutex); 158#ifdef CONFIG_QOS_CTRL 159 qos_switch(auth, AUTH_STATUS_DISABLED); 160#endif 161 auth->status = AUTH_STATUS_DEAD; 162 mutex_unlock(&auth->mutex); 163 put_auth_struct(auth); 164 165 return 0; 166} 167 168void remove_authority_control(void) 169{ 170 int ret; 171 172 mutex_lock(&ua_idr_mutex); 173 ret = idr_for_each(ua_idr, authority_remove_handler, NULL); 174 if (ret < 0) 175 pr_err("[AUTH_CTRL] authority item remove failed\n"); 176 177 idr_destroy(ua_idr); 178 kfree(ua_idr); 179 180 mutex_unlock(&ua_idr_mutex); 181} 182 183/* 184 * constrain user assigned auth_flag to kernel accepted auth_flag 185 */ 186static int generic_auth_trim(unsigned int orig_flag, unsigned int constrain) 187{ 188 return orig_flag & constrain; 189} 190 191static inline void set_auth_flag(struct auth_ctrl_data *data, struct auth_struct *auth_to_enable) 192{ 193#ifdef CONFIG_RTG_AUTHORITY 194 auth_to_enable->rtg_auth_flag = generic_auth_trim(data->rtg_ua_flag, AF_RTG_DELEGATED); 195#endif 196#ifdef CONFIG_QOS_AUTHORITY 197 auth_to_enable->qos_auth_flag = generic_auth_trim(data->qos_ua_flag, AF_QOS_ALL); 198#endif 199} 200 201static int auth_enable(struct auth_ctrl_data *data) 202{ 203 struct auth_struct *auth_to_enable; 204 unsigned int tgid = data->pid; 205 int status = data->status; 206 int ret; 207 208 mutex_lock(&ua_idr_mutex); 209 auth_to_enable = idr_find(ua_idr, tgid); 210 /* auth exist, just resume the task's qos request */ 211 if (auth_to_enable) { 212 get_auth_struct(auth_to_enable); 213 mutex_unlock(&ua_idr_mutex); 214 215 mutex_lock(&auth_to_enable->mutex); 216 if (auth_to_enable->status == AUTH_STATUS_DEAD) { 217 mutex_unlock(&auth_to_enable->mutex); 218 put_auth_struct(auth_to_enable); 219 return -INVALID_AUTH; 220 } 221 222 set_auth_flag(data, auth_to_enable); 223#ifdef CONFIG_QOS_CTRL 224 qos_switch(auth_to_enable, status); 225#endif 226 auth_to_enable->status = status; 227 mutex_unlock(&auth_to_enable->mutex); 228 ret = 0; 229 put_auth_struct(auth_to_enable); 230 goto out; 231 } 232 233 /* auth not exist, build a new auth, then insert to idr */ 234 auth_to_enable = kzalloc(sizeof(*auth_to_enable), GFP_ATOMIC); 235 if (!auth_to_enable) { 236 mutex_unlock(&ua_idr_mutex); 237 pr_err("[AUTH_CTRL] alloc auth data failed, no memory!\n"); 238 ret = -ENOMEM; 239 goto out; 240 } 241 242 init_authority_record(auth_to_enable); 243 244 /* no one could get the auth from idr now, no need to lock */ 245 set_auth_flag(data, auth_to_enable); 246 auth_to_enable->status = status; 247 248 ret = idr_alloc(ua_idr, auth_to_enable, tgid, tgid + 1, GFP_ATOMIC); 249 if (ret < 0) { 250 pr_err("[AUTH_CTRL] add auth to idr failed, no memory!\n"); 251 kfree(auth_to_enable); 252 } 253 254 mutex_unlock(&ua_idr_mutex); 255 256out: 257 return ret; 258} 259 260static int auth_delete(struct auth_ctrl_data *data) 261{ 262 struct auth_struct *auth_to_delete; 263 unsigned int tgid = data->pid; 264 265 mutex_lock(&ua_idr_mutex); 266 auth_to_delete = (struct auth_struct *)idr_remove(ua_idr, tgid); 267 if (!auth_to_delete) { 268 mutex_unlock(&ua_idr_mutex); 269 pr_err("[AUTH_CTRL] no auth data for this pid=%d, delete failed\n", tgid); 270 return -PID_NOT_FOUND; 271 } 272 mutex_unlock(&ua_idr_mutex); 273 274 mutex_lock(&auth_to_delete->mutex); 275#ifdef CONFIG_QOS_CTRL 276 qos_switch(auth_to_delete, AUTH_STATUS_DISABLED); 277#endif 278 auth_to_delete->status = AUTH_STATUS_DEAD; 279 mutex_unlock(&auth_to_delete->mutex); 280 281 put_auth_struct(auth_to_delete); 282 283 return 0; 284} 285 286static int auth_get(struct auth_ctrl_data *data) 287{ 288 struct auth_struct *auth_to_get; 289 unsigned int tgid = data->pid; 290 291 mutex_lock(&ua_idr_mutex); 292 auth_to_get = idr_find(ua_idr, tgid); 293 if (!auth_to_get) { 294 mutex_unlock(&ua_idr_mutex); 295 pr_err("[AUTH_CTRL] no auth data for this pid=%d to get\n", tgid); 296 return -PID_NOT_FOUND; 297 } 298 get_auth_struct(auth_to_get); 299 mutex_unlock(&ua_idr_mutex); 300 301 mutex_lock(&auth_to_get->mutex); 302 if (auth_to_get->status == AUTH_STATUS_DEAD) { 303 mutex_unlock(&auth_to_get->mutex); 304 put_auth_struct(auth_to_get); 305 return -INVALID_AUTH; 306 } 307#ifdef CONFIG_RTG_AUTHORITY 308 data->rtg_ua_flag = auth_to_get->rtg_auth_flag; 309#endif 310#ifdef CONFIG_QOS_AUTHORITY 311 data->qos_ua_flag = auth_to_get->qos_auth_flag; 312#endif 313 data->status = auth_to_get->status; 314 mutex_unlock(&auth_to_get->mutex); 315 316 put_auth_struct(auth_to_get); 317 318 return 0; 319} 320 321static int auth_switch(struct auth_ctrl_data *data) 322{ 323 struct auth_struct *auth; 324 unsigned int tgid = data->pid; 325 unsigned int status = data->status; 326 327 if (status == 0 || status >= AUTH_STATUS_MAX_NR) { 328 pr_err("[AUTH_CTRL] not valied status %d\n", status); 329 return -ARG_INVALID; 330 } 331 332 mutex_lock(&ua_idr_mutex); 333 auth = idr_find(ua_idr, tgid); 334 if (!auth) { 335 mutex_unlock(&ua_idr_mutex); 336 pr_err("[AUTH_CTRL] no auth data for this pid=%d to switch\n", tgid); 337 return -PID_NOT_FOUND; 338 } 339 get_auth_struct(auth); 340 mutex_unlock(&ua_idr_mutex); 341 342 mutex_lock(&auth->mutex); 343 if (auth->status == AUTH_STATUS_DEAD) { 344 mutex_unlock(&auth->mutex); 345 put_auth_struct(auth); 346 return -INVALID_AUTH; 347 } 348 349 set_auth_flag(data, auth); 350#ifdef CONFIG_QOS_CTRL 351 qos_switch(auth, status); 352#endif 353 auth->status = status; 354 mutex_unlock(&auth->mutex); 355 356 put_auth_struct(auth); 357 358 return 0; 359} 360 361typedef int (*auth_manipulate_func)(struct auth_ctrl_data *data); 362 363static auth_manipulate_func auth_func_array[AUTH_MAX_NR] = { 364 /* 365 * auth_enable: Start authority control for specific tgid. 366 * auth_delte: End authroity control, remove statistic datas. 367 * auth_get: Get auth info, deprecated. 368 * auth_switch: Change authority flag and status for specific tgid. 369 */ 370 NULL, 371 auth_enable, 372 auth_delete, 373 auth_get, 374 auth_switch, 375}; 376 377static long do_auth_manipulate(struct auth_ctrl_data *data) 378{ 379 long ret = 0; 380 unsigned int type = data->type; 381 382 if (type >= AUTH_MAX_NR) { 383 pr_err("[AUTH_CTRL] BASIC_AUTH_CTRL_OPERATION type not valid\n"); 384 return -ARG_INVALID; 385 } 386 387 if (auth_func_array[type]) 388 ret = (long)(*auth_func_array[type])(data); 389 390 return ret; 391} 392 393static long ctrl_auth_basic_operation(int abi, void __user *uarg) 394{ 395 struct auth_ctrl_data auth_data; 396 long ret = -1; 397 398#pragma GCC diagnostic push 399#pragma GCC diagnostic ignored "-Wpointer-to-int-cast" 400 401 switch (abi) { 402 case AUTH_IOCTL_ABI_ARM32: 403 ret = copy_from_user(&auth_data, 404 (void __user *)compat_ptr((compat_uptr_t)uarg), 405 sizeof(struct auth_ctrl_data)); 406 break; 407 case AUTH_IOCTL_ABI_AARCH64: 408 ret = copy_from_user(&auth_data, uarg, sizeof(struct auth_ctrl_data)); 409 break; 410 default: 411 pr_err("[AUTH_CTRL] abi format error\n"); 412 break; 413 } 414 415#pragma GCC diagnostic pop 416 417 if (ret) { 418 pr_err("[AUTH_RTG] %s copy user data failed\n", __func__); 419 return ret; 420 } 421 422 ret = do_auth_manipulate(&auth_data); 423 if (ret < 0) { 424 pr_err("[AUTH_CTRL] BASIC_AUTH_CTRL_OPERATION failed\n"); 425 return ret; 426 } 427 428#pragma GCC diagnostic push 429#pragma GCC diagnostic ignored "-Wpointer-to-int-cast" 430 431 switch (abi) { 432 case AUTH_IOCTL_ABI_ARM32: 433 ret = copy_to_user((void __user *)compat_ptr((compat_uptr_t)uarg), 434 &auth_data, 435 sizeof(struct auth_ctrl_data)); 436 break; 437 case AUTH_IOCTL_ABI_AARCH64: 438 ret = copy_to_user(uarg, &auth_data, sizeof(struct auth_ctrl_data)); 439 break; 440 default: 441 pr_err("[AUTH_CTRL] abi format error\n"); 442 break; 443 } 444 445#pragma GCC diagnostic pop 446 447 if (ret) { 448 pr_err("[AUTH_RTG] %s copy user data failed\n", __func__); 449 return ret; 450 } 451 452 return 0; 453} 454 455long do_auth_ctrl_ioctl(int abi, struct file *file, unsigned int cmd, unsigned long arg) 456{ 457 void __user *uarg = (void __user *)arg; 458 unsigned int func_cmd = _IOC_NR(cmd); 459 460 if (uarg == NULL) { 461 pr_err("%s: invalid user uarg\n", __func__); 462 return -EINVAL; 463 } 464 465 if (_IOC_TYPE(cmd) != AUTH_CTRL_IPC_MAGIG) { 466 pr_err("%s: authority ctrl magic fail, TYPE=%d\n", 467 __func__, _IOC_TYPE(cmd)); 468 return -EINVAL; 469 } 470 471 if (func_cmd >= AUTH_CTRL_MAX_NR) { 472 pr_err("%s: authority ctrl cmd error, cmd:%d\n", 473 __func__, _IOC_TYPE(cmd)); 474 return -EINVAL; 475 } 476 477 if (g_func_array[func_cmd]) 478 return (*g_func_array[func_cmd])(abi, uarg); 479 480 return -EINVAL; 481} 482 483#define get_authority_flag(func_id) (1 << (func_id - 1)) 484 485static inline unsigned int get_true_uid(struct task_struct *p) 486{ 487 if (!p) 488 return get_uid(current_user())->uid.val; 489 490 return task_uid(p).val; 491} 492 493/* 494 * Return 1000 for both SYSTEM and ROOT 495 * Return current's uid if p is NULL 496 */ 497static inline unsigned int get_authority_uid(struct task_struct *p) 498{ 499 unsigned int uid = get_true_uid(p); 500 501 if (super_uid(uid)) 502 uid = SUPER_UID; 503 504 return uid; 505} 506 507static unsigned int auth_flag(struct auth_struct *auth, unsigned int type) 508{ 509 switch (type) { 510#ifdef CONFIG_RTG_AUTHORITY 511 case RTG_AUTH_FLAG: 512 return auth->rtg_auth_flag; 513#endif 514#ifdef CONFIG_QOS_AUTHORITY 515 case QOS_AUTH_FLAG: 516 return auth->qos_auth_flag; 517#endif 518 default: 519 pr_err("[AUTH_CTRL] not valid auth type\n"); 520 return INVALIED_AUTH_FLAG; 521 } 522} 523 524bool check_authorized(unsigned int func_id, unsigned int type) 525{ 526 bool authorized = false; 527 struct auth_struct *auth; 528 unsigned int af = get_authority_flag(func_id); 529 unsigned int uid = get_authority_uid(NULL); 530 unsigned int tgid = task_tgid_nr(current); 531 532 mutex_lock(&ua_idr_mutex); 533 if (!ua_idr) { 534 mutex_unlock(&ua_idr_mutex); 535 pr_err("[AUTH_CTRL] authority idr table missed, auth failed\n"); 536 return authorized; 537 } 538 539 auth = (struct auth_struct *)idr_find(ua_idr, tgid); 540 if (!auth) { 541 if (uid != SUPER_UID) { 542 mutex_unlock(&ua_idr_mutex); 543 pr_err("[AUTH_CTRL] no auth data for this pid = %d\n, tgid"); 544 return authorized; 545 } else if (init_super_authority(tgid)) { 546 mutex_unlock(&ua_idr_mutex); 547 pr_err("[AUTH_CTRL] init super authority failed\n"); 548 return authorized; 549 } 550 551 //the auth must exist 552 auth = (struct auth_struct *)idr_find(ua_idr, tgid); 553 if (!auth) 554 return authorized; 555 } 556 557 get_auth_struct(auth); 558 mutex_unlock(&ua_idr_mutex); 559 560 mutex_lock(&auth->mutex); 561 if (auth->status == AUTH_STATUS_DEAD) { 562 mutex_unlock(&auth->mutex); 563 pr_info("[AUTH_CTRL] not valid auth for pid %d\n", tgid); 564 put_auth_struct(auth); 565 return authorized; 566 } 567 if (auth && (auth_flag(auth, type) & af)) 568 authorized = true; 569 570 mutex_unlock(&auth->mutex); 571 572 put_auth_struct(auth); 573 574 return authorized; 575} 576 577/* 578 * Return authority info for given task 579 * return current's auth if p is NULL 580 * refcount will inc if this call return the valid auth 581 * make sure to call put_auth_struct before the calling end 582 */ 583struct auth_struct *get_authority(struct task_struct *p) 584{ 585 unsigned int tgid; 586 struct auth_struct *auth; 587 588 tgid = (p == NULL ? current->tgid : p->tgid); 589 590 mutex_lock(&ua_idr_mutex); 591 auth = idr_find(ua_idr, tgid); 592 if (auth) 593 get_auth_struct(auth); 594 595 mutex_unlock(&ua_idr_mutex); 596 597 return auth; 598} 599 600long proc_auth_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 601{ 602 return do_auth_ctrl_ioctl(AUTH_IOCTL_ABI_AARCH64, file, cmd, arg); 603} 604 605#ifdef CONFIG_COMPAT 606long proc_auth_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 607{ 608 return do_auth_ctrl_ioctl(AUTH_IOCTL_ABI_ARM32, file, cmd, 609 (unsigned long)(compat_ptr((compat_uptr_t)arg))); 610} 611#endif 612 613static const struct file_operations auth_ctrl_fops = { 614 .owner = THIS_MODULE, 615 .unlocked_ioctl = proc_auth_ioctl, 616#ifdef CONFIG_COMPAT 617 .compat_ioctl = proc_auth_compat_ioctl, 618#endif 619}; 620 621static struct miscdevice auth_ctrl_device = { 622 .minor = MISC_DYNAMIC_MINOR, 623 .name = "auth_ctrl", 624 .fops = &auth_ctrl_fops, 625}; 626 627static __init int auth_ctrl_init_module(void) 628{ 629 int err; 630 631 err = misc_register(&auth_ctrl_device); 632 if (err < 0) { 633 pr_err("auth_ctrl register failed\n"); 634 return err; 635 } 636 637 pr_info("auth_ctrl init success\n"); 638 639 BUG_ON(init_ua_idr()); 640 641#ifdef CONFIG_QOS_CTRL 642 init_qos_ctrl(); 643#endif 644 645 init_sched_auth_debug_procfs(); 646 647 return 0; 648} 649 650static void auth_ctrl_exit_module(void) 651{ 652 remove_authority_control(); 653 misc_deregister(&auth_ctrl_device); 654} 655 656/* module entry points */ 657module_init(auth_ctrl_init_module); 658module_exit(auth_ctrl_exit_module); 659 660MODULE_LICENSE("GPL v2"); 661 662