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