• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2023 Huawei Device Co., Ltd.
4 */
5 #include <linux/mman.h>
6 #include <linux/mm_types.h>
7 #include <linux/sched.h>
8 #include <linux/mm.h>
9 
10 #include "jit_memory.h"
11 #include "jit_space_list.h"
12 #include "avc.h"
13 #include "objsec.h"
14 
15 DEFINE_SPINLOCK(list_lock);
16 
jit_avc_has_perm(u16 tclass,u32 requested,struct task_struct * task)17 static bool jit_avc_has_perm(u16 tclass, u32 requested, struct task_struct *task)
18 {
19 	// Bypass 'init'
20 	if (task_pid_nr(current) == 1) {
21 		return false;
22 	}
23 
24 	struct av_decision avd;
25 	u32 secid;
26 	security_cred_getsecid(task->cred, &secid);
27 
28 	return (avc_has_perm_noaudit(&selinux_state, secid, secid, tclass, requested,
29 		AVC_STRICT, &avd) == 0);
30 }
31 
find_jit_memory(struct task_struct * task,unsigned long start,unsigned long size,int * err)32 void find_jit_memory(struct task_struct *task, unsigned long start, unsigned long size, int *err)
33 {
34 	if (!jit_avc_has_perm(SECCLASS_JIT_MEMORY, JIT_MEMORY__EXEC_MEM_CTRL, task))
35 		return;
36 
37 	struct list_head *head = (find_process_jit_space(&root_tree, task->pid).head);
38 	if (head != NULL) {
39 		spin_lock(&list_lock);
40 		find_jit_space(head, start, size, err);
41 		spin_unlock(&list_lock);
42 	}
43 
44 }
45 
check_jit_memory(struct task_struct * task,unsigned long cookie,unsigned long prot,unsigned long flag,unsigned long size,unsigned long * err)46 void check_jit_memory(struct task_struct *task, unsigned long cookie, unsigned long prot,
47 	unsigned long flag, unsigned long size, unsigned long *err)
48 {
49 	if (!jit_avc_has_perm(SECCLASS_JIT_MEMORY, JIT_MEMORY__EXEC_MEM_CTRL, task) || !(flag & MAP_ANONYMOUS))
50 		return;
51 	unsigned long start = *err;
52 
53 	if (prot & PROT_EXEC) {
54 		jit_memory_log_info("can not apply prot_exec");
55 		*err = -EACCES;
56 		vm_munmap(start, size);
57 		return;
58 	}
59 	if (!(flag & MAP_JIT))
60 		return;
61 
62 	struct list_head *head = update_process_jit_space(&root_tree, task->pid, cookie, err);
63 	if (IS_ERR_VALUE(*err)) {
64 		vm_munmap(start, size);
65 		return;
66 	}
67 	if (head != NULL) {
68 		spin_lock(&list_lock);
69 		update_jit_space(head, start, size);
70 		spin_unlock(&list_lock);
71 	}
72 }
73 
delete_jit_memory(struct task_struct * task,unsigned long start,unsigned long size,int * err)74 void delete_jit_memory(struct task_struct *task, unsigned long start, unsigned long size, int *err)
75 {
76 	if (!jit_avc_has_perm(SECCLASS_JIT_MEMORY, JIT_MEMORY__EXEC_MEM_CTRL, task))
77 		return;
78 
79 	struct list_head *head = (find_process_jit_space(&root_tree, task->pid).head);
80 	if (head != NULL) {
81 		spin_lock(&list_lock);
82 		delete_jit_space(head, start, size, err);
83 		spin_unlock(&list_lock);
84 	}
85 }
86 
exit_jit_memory(struct task_struct * task)87 void exit_jit_memory(struct task_struct *task)
88 {
89 	if (!jit_avc_has_perm(SECCLASS_JIT_MEMORY, JIT_MEMORY__EXEC_MEM_CTRL, task))
90 		return;
91 
92 	struct jit_process *process = delete_process_jit_space(&root_tree, task->pid);
93 	if (process != NULL) {
94 		spin_lock(&list_lock);
95 		exit_jit_space(&(process->head));
96 		spin_unlock(&list_lock);
97 		kfree(process);
98 	}
99 }