xref: /linux/security/ipe/fs.c (revision 2261306f4a3cea362fc40285e750a801dc0cfbe3)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved.
4  */
5 
6 #include <linux/dcache.h>
7 #include <linux/security.h>
8 
9 #include "ipe.h"
10 #include "fs.h"
11 #include "policy.h"
12 
13 static struct dentry *np __ro_after_init;
14 static struct dentry *root __ro_after_init;
15 struct dentry *policy_root __ro_after_init;
16 
17 /**
18  * new_policy() - Write handler for the securityfs node, "ipe/new_policy".
19  * @f: Supplies a file structure representing the securityfs node.
20  * @data: Supplies a buffer passed to the write syscall.
21  * @len: Supplies the length of @data.
22  * @offset: unused.
23  *
24  * Return:
25  * * Length of buffer written	- Success
26  * * %-EPERM			- Insufficient permission
27  * * %-ENOMEM			- Out of memory (OOM)
28  * * %-EBADMSG			- Policy is invalid
29  * * %-ERANGE			- Policy version number overflow
30  * * %-EINVAL			- Policy version parsing error
31  * * %-EEXIST			- Same name policy already deployed
32  */
33 static ssize_t new_policy(struct file *f, const char __user *data,
34 			  size_t len, loff_t *offset)
35 {
36 	struct ipe_policy *p = NULL;
37 	char *copy = NULL;
38 	int rc = 0;
39 
40 	if (!file_ns_capable(f, &init_user_ns, CAP_MAC_ADMIN))
41 		return -EPERM;
42 
43 	copy = memdup_user_nul(data, len);
44 	if (IS_ERR(copy))
45 		return PTR_ERR(copy);
46 
47 	p = ipe_new_policy(NULL, 0, copy, len);
48 	if (IS_ERR(p)) {
49 		rc = PTR_ERR(p);
50 		goto out;
51 	}
52 
53 	rc = ipe_new_policyfs_node(p);
54 
55 out:
56 	if (rc < 0)
57 		ipe_free_policy(p);
58 	kfree(copy);
59 	return (rc < 0) ? rc : len;
60 }
61 
62 static const struct file_operations np_fops = {
63 	.write = new_policy,
64 };
65 
66 /**
67  * ipe_init_securityfs() - Initialize IPE's securityfs tree at fsinit.
68  *
69  * Return: %0 on success. If an error occurs, the function will return
70  * the -errno.
71  */
72 static int __init ipe_init_securityfs(void)
73 {
74 	int rc = 0;
75 
76 	if (!ipe_enabled)
77 		return -EOPNOTSUPP;
78 
79 	root = securityfs_create_dir("ipe", NULL);
80 	if (IS_ERR(root)) {
81 		rc = PTR_ERR(root);
82 		goto err;
83 	}
84 
85 	policy_root = securityfs_create_dir("policies", root);
86 	if (IS_ERR(policy_root)) {
87 		rc = PTR_ERR(policy_root);
88 		goto err;
89 	}
90 
91 	np = securityfs_create_file("new_policy", 0200, root, NULL, &np_fops);
92 	if (IS_ERR(np)) {
93 		rc = PTR_ERR(np);
94 		goto err;
95 	}
96 
97 	return 0;
98 err:
99 	securityfs_remove(np);
100 	securityfs_remove(policy_root);
101 	securityfs_remove(root);
102 	return rc;
103 }
104 
105 fs_initcall(ipe_init_securityfs);
106