1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved.
6 #include <linux/namei.h>
7 #include <linux/types.h>
8 #include <linux/dcache.h>
9 #include <linux/security.h>
16 #define MAX_VERSION_SIZE ARRAY_SIZE("65535.65535.65535")
19 * ipefs_file - defines a file in securityfs.
24 const struct file_operations *fops;
28 * read_pkcs7() - Read handler for "ipe/policies/$name/pkcs7".
29 * @f: Supplies a file structure representing the securityfs node.
30 * @data: Supplies a buffer passed to the write syscall.
31 * @len: Supplies the length of @data.
34 * @data will be populated with the pkcs7 blob representing the policy
35 * on success. If the policy is unsigned (like the boot policy), this
36 * will return -ENOENT.
39 * * Length of buffer written - Success
40 * * %-ENOENT - Policy initializing/deleted or is unsigned
42 static ssize_t read_pkcs7(struct file *f, char __user *data,
43 size_t len, loff_t *offset)
45 const struct ipe_policy *p = NULL;
46 struct inode *root = NULL;
49 root = d_inode(f->f_path.dentry->d_parent);
51 inode_lock_shared(root);
52 p = (struct ipe_policy *)root->i_private;
63 rc = simple_read_from_buffer(data, len, offset, p->pkcs7, p->pkcs7len);
66 inode_unlock_shared(root);
72 * read_policy() - Read handler for "ipe/policies/$name/policy".
73 * @f: Supplies a file structure representing the securityfs node.
74 * @data: Supplies a buffer passed to the write syscall.
75 * @len: Supplies the length of @data.
78 * @data will be populated with the plain-text version of the policy
82 * * Length of buffer written - Success
83 * * %-ENOENT - Policy initializing/deleted
85 static ssize_t read_policy(struct file *f, char __user *data,
86 size_t len, loff_t *offset)
88 const struct ipe_policy *p = NULL;
89 struct inode *root = NULL;
92 root = d_inode(f->f_path.dentry->d_parent);
94 inode_lock_shared(root);
95 p = (struct ipe_policy *)root->i_private;
101 rc = simple_read_from_buffer(data, len, offset, p->text, p->textlen);
104 inode_unlock_shared(root);
110 * read_name() - Read handler for "ipe/policies/$name/name".
111 * @f: Supplies a file structure representing the securityfs node.
112 * @data: Supplies a buffer passed to the write syscall.
113 * @len: Supplies the length of @data.
116 * @data will be populated with the policy_name attribute on success.
119 * * Length of buffer written - Success
120 * * %-ENOENT - Policy initializing/deleted
122 static ssize_t read_name(struct file *f, char __user *data,
123 size_t len, loff_t *offset)
125 const struct ipe_policy *p = NULL;
126 struct inode *root = NULL;
129 root = d_inode(f->f_path.dentry->d_parent);
131 inode_lock_shared(root);
132 p = (struct ipe_policy *)root->i_private;
138 rc = simple_read_from_buffer(data, len, offset, p->parsed->name,
139 strlen(p->parsed->name));
142 inode_unlock_shared(root);
148 * read_version() - Read handler for "ipe/policies/$name/version".
149 * @f: Supplies a file structure representing the securityfs node.
150 * @data: Supplies a buffer passed to the write syscall.
151 * @len: Supplies the length of @data.
154 * @data will be populated with the version string on success.
157 * * Length of buffer written - Success
158 * * %-ENOENT - Policy initializing/deleted
160 static ssize_t read_version(struct file *f, char __user *data,
161 size_t len, loff_t *offset)
163 char buffer[MAX_VERSION_SIZE] = { 0 };
164 const struct ipe_policy *p = NULL;
165 struct inode *root = NULL;
169 root = d_inode(f->f_path.dentry->d_parent);
171 inode_lock_shared(root);
172 p = (struct ipe_policy *)root->i_private;
178 strsize = scnprintf(buffer, ARRAY_SIZE(buffer), "%hu.%hu.%hu",
179 p->parsed->version.major, p->parsed->version.minor,
180 p->parsed->version.rev);
182 rc = simple_read_from_buffer(data, len, offset, buffer, strsize);
185 inode_unlock_shared(root);
191 * setactive() - Write handler for "ipe/policies/$name/active".
192 * @f: Supplies a file structure representing the securityfs node.
193 * @data: Supplies a buffer passed to the write syscall.
194 * @len: Supplies the length of @data.
198 * * Length of buffer written - Success
199 * * %-EPERM - Insufficient permission
200 * * %-EINVAL - Invalid input
201 * * %-ENOENT - Policy initializing/deleted
203 static ssize_t setactive(struct file *f, const char __user *data,
204 size_t len, loff_t *offset)
206 const struct ipe_policy *p = NULL;
207 struct inode *root = NULL;
211 if (!file_ns_capable(f, &init_user_ns, CAP_MAC_ADMIN))
214 rc = kstrtobool_from_user(data, len, &value);
221 root = d_inode(f->f_path.dentry->d_parent);
224 p = (struct ipe_policy *)root->i_private;
230 rc = ipe_set_active_pol(p);
234 return (rc < 0) ? rc : len;
238 * getactive() - Read handler for "ipe/policies/$name/active".
239 * @f: Supplies a file structure representing the securityfs node.
240 * @data: Supplies a buffer passed to the write syscall.
241 * @len: Supplies the length of @data.
244 * @data will be populated with the 1 or 0 depending on if the
245 * corresponding policy is active.
248 * * Length of buffer written - Success
249 * * %-ENOENT - Policy initializing/deleted
251 static ssize_t getactive(struct file *f, char __user *data,
252 size_t len, loff_t *offset)
254 const struct ipe_policy *p = NULL;
255 struct inode *root = NULL;
259 root = d_inode(f->f_path.dentry->d_parent);
261 inode_lock_shared(root);
262 p = (struct ipe_policy *)root->i_private;
264 inode_unlock_shared(root);
267 inode_unlock_shared(root);
269 str = (p == rcu_access_pointer(ipe_active_policy)) ? "1" : "0";
270 rc = simple_read_from_buffer(data, len, offset, str, 1);
276 * update_policy() - Write handler for "ipe/policies/$name/update".
277 * @f: Supplies a file structure representing the securityfs node.
278 * @data: Supplies a buffer passed to the write syscall.
279 * @len: Supplies the length of @data.
282 * On success this updates the policy represented by $name,
285 * Return: Length of buffer written on success. If an error occurs,
286 * the function will return the -errno.
288 static ssize_t update_policy(struct file *f, const char __user *data,
289 size_t len, loff_t *offset)
291 struct inode *root = NULL;
295 if (!file_ns_capable(f, &init_user_ns, CAP_MAC_ADMIN))
298 copy = memdup_user(data, len);
300 return PTR_ERR(copy);
302 root = d_inode(f->f_path.dentry->d_parent);
304 rc = ipe_update_policy(root, NULL, 0, copy, len);
315 * delete_policy() - write handler for "ipe/policies/$name/delete".
316 * @f: Supplies a file structure representing the securityfs node.
317 * @data: Supplies a buffer passed to the write syscall.
318 * @len: Supplies the length of @data.
321 * On success this deletes the policy represented by $name.
324 * * Length of buffer written - Success
325 * * %-EPERM - Insufficient permission/deleting active policy
326 * * %-EINVAL - Invalid input
327 * * %-ENOENT - Policy initializing/deleted
329 static ssize_t delete_policy(struct file *f, const char __user *data,
330 size_t len, loff_t *offset)
332 struct ipe_policy *ap = NULL;
333 struct ipe_policy *p = NULL;
334 struct inode *root = NULL;
338 if (!file_ns_capable(f, &init_user_ns, CAP_MAC_ADMIN))
341 rc = kstrtobool_from_user(data, len, &value);
348 root = d_inode(f->f_path.dentry->d_parent);
350 p = (struct ipe_policy *)root->i_private;
356 mutex_lock(&ipe_policy_lock);
357 ap = rcu_dereference_protected(ipe_active_policy,
358 lockdep_is_held(&ipe_policy_lock));
360 mutex_unlock(&ipe_policy_lock);
364 mutex_unlock(&ipe_policy_lock);
366 root->i_private = NULL;
375 static const struct file_operations content_fops = {
379 static const struct file_operations pkcs7_fops = {
383 static const struct file_operations name_fops = {
387 static const struct file_operations ver_fops = {
388 .read = read_version,
391 static const struct file_operations active_fops = {
396 static const struct file_operations update_fops = {
397 .write = update_policy,
400 static const struct file_operations delete_fops = {
401 .write = delete_policy,
405 * policy_subdir - files under a policy subdirectory
407 static const struct ipefs_file policy_subdir[] = {
408 { "pkcs7", 0444, &pkcs7_fops },
409 { "policy", 0444, &content_fops },
410 { "name", 0444, &name_fops },
411 { "version", 0444, &ver_fops },
412 { "active", 0600, &active_fops },
413 { "update", 0200, &update_fops },
414 { "delete", 0200, &delete_fops },
418 * ipe_del_policyfs_node() - Delete a securityfs entry for @p.
419 * @p: Supplies a pointer to the policy to delete a securityfs entry for.
421 void ipe_del_policyfs_node(struct ipe_policy *p)
423 securityfs_recursive_remove(p->policyfs);
428 * ipe_new_policyfs_node() - Create a securityfs entry for @p.
429 * @p: Supplies a pointer to the policy to create a securityfs entry for.
431 * Return: %0 on success. If an error occurs, the function will return
434 int ipe_new_policyfs_node(struct ipe_policy *p)
436 const struct ipefs_file *f = NULL;
437 struct dentry *policyfs = NULL;
438 struct inode *root = NULL;
439 struct dentry *d = NULL;
446 policyfs = securityfs_create_dir(p->parsed->name, policy_root);
447 if (IS_ERR(policyfs))
448 return PTR_ERR(policyfs);
450 root = d_inode(policyfs);
452 for (i = 0; i < ARRAY_SIZE(policy_subdir); ++i) {
453 f = &policy_subdir[i];
455 d = securityfs_create_file(f->name, f->access, policyfs,
464 p->policyfs = policyfs;
470 securityfs_recursive_remove(policyfs);