0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/slab.h>
0015 #include <linux/init.h>
0016 #include <linux/spinlock.h>
0017 #include <linux/rbtree.h>
0018 #include <linux/file.h>
0019 #include <linux/uaccess.h>
0020 #include <linux/security.h>
0021 #include <linux/lsm_hooks.h>
0022 #include "integrity.h"
0023
0024 static struct rb_root integrity_iint_tree = RB_ROOT;
0025 static DEFINE_RWLOCK(integrity_iint_lock);
0026 static struct kmem_cache *iint_cache __read_mostly;
0027
0028 struct dentry *integrity_dir;
0029
0030
0031
0032
0033 static struct integrity_iint_cache *__integrity_iint_find(struct inode *inode)
0034 {
0035 struct integrity_iint_cache *iint;
0036 struct rb_node *n = integrity_iint_tree.rb_node;
0037
0038 while (n) {
0039 iint = rb_entry(n, struct integrity_iint_cache, rb_node);
0040
0041 if (inode < iint->inode)
0042 n = n->rb_left;
0043 else if (inode > iint->inode)
0044 n = n->rb_right;
0045 else
0046 break;
0047 }
0048 if (!n)
0049 return NULL;
0050
0051 return iint;
0052 }
0053
0054
0055
0056
0057 struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
0058 {
0059 struct integrity_iint_cache *iint;
0060
0061 if (!IS_IMA(inode))
0062 return NULL;
0063
0064 read_lock(&integrity_iint_lock);
0065 iint = __integrity_iint_find(inode);
0066 read_unlock(&integrity_iint_lock);
0067
0068 return iint;
0069 }
0070
0071 static void iint_free(struct integrity_iint_cache *iint)
0072 {
0073 kfree(iint->ima_hash);
0074 iint->ima_hash = NULL;
0075 iint->version = 0;
0076 iint->flags = 0UL;
0077 iint->atomic_flags = 0UL;
0078 iint->ima_file_status = INTEGRITY_UNKNOWN;
0079 iint->ima_mmap_status = INTEGRITY_UNKNOWN;
0080 iint->ima_bprm_status = INTEGRITY_UNKNOWN;
0081 iint->ima_read_status = INTEGRITY_UNKNOWN;
0082 iint->ima_creds_status = INTEGRITY_UNKNOWN;
0083 iint->evm_status = INTEGRITY_UNKNOWN;
0084 iint->measured_pcrs = 0;
0085 kmem_cache_free(iint_cache, iint);
0086 }
0087
0088
0089
0090
0091
0092
0093
0094
0095 struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
0096 {
0097 struct rb_node **p;
0098 struct rb_node *node, *parent = NULL;
0099 struct integrity_iint_cache *iint, *test_iint;
0100
0101
0102
0103
0104
0105
0106 if (!iint_cache)
0107 panic("%s: lsm=integrity required.\n", __func__);
0108
0109 iint = integrity_iint_find(inode);
0110 if (iint)
0111 return iint;
0112
0113 iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
0114 if (!iint)
0115 return NULL;
0116
0117 write_lock(&integrity_iint_lock);
0118
0119 p = &integrity_iint_tree.rb_node;
0120 while (*p) {
0121 parent = *p;
0122 test_iint = rb_entry(parent, struct integrity_iint_cache,
0123 rb_node);
0124 if (inode < test_iint->inode)
0125 p = &(*p)->rb_left;
0126 else
0127 p = &(*p)->rb_right;
0128 }
0129
0130 iint->inode = inode;
0131 node = &iint->rb_node;
0132 inode->i_flags |= S_IMA;
0133 rb_link_node(node, parent, p);
0134 rb_insert_color(node, &integrity_iint_tree);
0135
0136 write_unlock(&integrity_iint_lock);
0137 return iint;
0138 }
0139
0140
0141
0142
0143
0144
0145
0146 void integrity_inode_free(struct inode *inode)
0147 {
0148 struct integrity_iint_cache *iint;
0149
0150 if (!IS_IMA(inode))
0151 return;
0152
0153 write_lock(&integrity_iint_lock);
0154 iint = __integrity_iint_find(inode);
0155 rb_erase(&iint->rb_node, &integrity_iint_tree);
0156 write_unlock(&integrity_iint_lock);
0157
0158 iint_free(iint);
0159 }
0160
0161 static void init_once(void *foo)
0162 {
0163 struct integrity_iint_cache *iint = (struct integrity_iint_cache *) foo;
0164
0165 memset(iint, 0, sizeof(*iint));
0166 iint->ima_file_status = INTEGRITY_UNKNOWN;
0167 iint->ima_mmap_status = INTEGRITY_UNKNOWN;
0168 iint->ima_bprm_status = INTEGRITY_UNKNOWN;
0169 iint->ima_read_status = INTEGRITY_UNKNOWN;
0170 iint->ima_creds_status = INTEGRITY_UNKNOWN;
0171 iint->evm_status = INTEGRITY_UNKNOWN;
0172 mutex_init(&iint->mutex);
0173 }
0174
0175 static int __init integrity_iintcache_init(void)
0176 {
0177 iint_cache =
0178 kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache),
0179 0, SLAB_PANIC, init_once);
0180 return 0;
0181 }
0182 DEFINE_LSM(integrity) = {
0183 .name = "integrity",
0184 .init = integrity_iintcache_init,
0185 };
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 int integrity_kernel_read(struct file *file, loff_t offset,
0197 void *addr, unsigned long count)
0198 {
0199 return __kernel_read(file, addr, count, &offset);
0200 }
0201
0202
0203
0204
0205
0206
0207
0208 void __init integrity_load_keys(void)
0209 {
0210 ima_load_x509();
0211
0212 if (!IS_ENABLED(CONFIG_IMA_LOAD_X509))
0213 evm_load_x509();
0214 }
0215
0216 static int __init integrity_fs_init(void)
0217 {
0218 integrity_dir = securityfs_create_dir("integrity", NULL);
0219 if (IS_ERR(integrity_dir)) {
0220 int ret = PTR_ERR(integrity_dir);
0221
0222 if (ret != -ENODEV)
0223 pr_err("Unable to create integrity sysfs dir: %d\n",
0224 ret);
0225 integrity_dir = NULL;
0226 return ret;
0227 }
0228
0229 return 0;
0230 }
0231
0232 late_initcall(integrity_fs_init)