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