1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2023 Huawei Device Co., Ltd.
4  */
5 
6 #include <internal.h>
7 #include <linux/security.h>
8 #include <linux/seq_file.h>
9 #include <linux/mm_types.h>
10 #include <linux/mm.h>
11 #include <linux/mm_inline.h>
12 #include <linux/hck/lite_hck_hideaddr.h>
13 #include <linux/hck/lite_vendor_hooks.h>
14 #include <linux/init.h>
15 #include <linux/module.h>
16 
17 #include "avc.h"
18 #include "objsec.h"
19 #include "hideaddr.h"
20 #include <linux/version.h>
21 
is_anon_exec(struct vm_area_struct *vma)22 static bool is_anon_exec(struct vm_area_struct *vma)
23 {
24 	const char *name = NULL;
25 	vm_flags_t flags = vma->vm_flags;
26 
27 	if (!(flags & VM_EXEC))
28 		return false;
29 
30 	name = arch_vma_name(vma);
31 	if (!name) {
32 		struct anon_vma_name *anon_name;
33 		anon_name = anon_vma_name(vma);
34 		if (!anon_name)
35 			return false;
36 	}
37 	return true;
38 }
39 
hideaddr_avc_has_perm(u16 tclass, u32 requested, struct seq_file *m)40 static int hideaddr_avc_has_perm(u16 tclass, u32 requested, struct seq_file *m)
41 {
42 	struct av_decision avd;
43 	struct inode *inode_task = file_inode(m->file);
44 	struct task_struct *task = get_proc_task(inode_task);
45 	u32 secid;
46 
47 	security_cred_getsecid(task->cred, &secid);
48 #if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
49 	return avc_has_perm_noaudit(&selinux_state, secid, secid, tclass, requested,
50 		AVC_STRICT, &avd);
51 #else
52 	return avc_has_perm_noaudit(secid, secid, tclass, requested,
53 		AVC_STRICT, &avd);
54 #endif
55 }
56 
hideaddr_header_prefix(unsigned long *start, unsigned long *end, vm_flags_t *flags, struct seq_file *m, struct vm_area_struct *vma)57 static void hideaddr_header_prefix(unsigned long *start, unsigned long *end,
58 			vm_flags_t *flags, struct seq_file *m, struct vm_area_struct *vma)
59 {
60 	if (!is_anon_exec(vma))
61 		return;
62 
63 	if (hideaddr_avc_has_perm(SECCLASS_HIDEADDR, HIDEADDR__HIDE_EXEC_ANON_MEM, m))
64 		return;
65 
66 	if (!hideaddr_avc_has_perm(SECCLASS_HIDEADDR, HIDEADDR__HIDE_EXEC_ANON_MEM_DEBUG, m))
67 		return;
68 
69 	*start = 0;
70 	*end = 0;
71 	*flags = 0;
72 }
73 
hideaddr_header_prefix_lhck_register(void)74 void hideaddr_header_prefix_lhck_register(void)
75 {
76 	REGISTER_HCK_LITE_HOOK(hideaddr_header_prefix_lhck, hideaddr_header_prefix);
77 }