]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
integrity: Remove LSM
authorRoberto Sassu <roberto.sassu@huawei.com>
Thu, 15 Feb 2024 10:31:13 +0000 (11:31 +0100)
committerPaul Moore <paul@paul-moore.com>
Fri, 16 Feb 2024 04:43:48 +0000 (23:43 -0500)
Since now IMA and EVM use their own integrity metadata, it is safe to
remove the 'integrity' LSM, with its management of integrity metadata.

Keep the iint.c file only for loading IMA and EVM keys at boot, and for
creating the integrity directory in securityfs (we need to keep it for
retrocompatibility reasons).

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Acked-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
include/linux/integrity.h
security/integrity/iint.c
security/integrity/integrity.h
security/security.c

index ef0f63ef5ebcc317a86c211114d14505d18e17dc..459b796837830df311cbc573e24d7c3b79f15613 100644 (file)
@@ -19,24 +19,10 @@ enum integrity_status {
        INTEGRITY_UNKNOWN,
 };
 
-/* List of EVM protected security xattrs */
 #ifdef CONFIG_INTEGRITY
-extern struct integrity_iint_cache *integrity_inode_get(struct inode *inode);
-extern void integrity_inode_free(struct inode *inode);
 extern void __init integrity_load_keys(void);
 
 #else
-static inline struct integrity_iint_cache *
-                               integrity_inode_get(struct inode *inode)
-{
-       return NULL;
-}
-
-static inline void integrity_inode_free(struct inode *inode)
-{
-       return;
-}
-
 static inline void integrity_load_keys(void)
 {
 }
index d4419a2a1e24be840d71b5ca8927c3d52f9704f7..068ac6c2ae1e7a8432c93c9044e81fbdc2f1147f 100644 (file)
  * Mimi Zohar <zohar@us.ibm.com>
  *
  * File: integrity_iint.c
- *     - implements the integrity hooks: integrity_inode_alloc,
- *       integrity_inode_free
- *     - cache integrity information associated with an inode
- *       using a rbtree tree.
+ *     - initialize the integrity directory in securityfs
+ *     - load IMA and EVM keys
  */
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/rbtree.h>
-#include <linux/file.h>
-#include <linux/uaccess.h>
 #include <linux/security.h>
-#include <linux/lsm_hooks.h>
 #include "integrity.h"
 
-static struct rb_root integrity_iint_tree = RB_ROOT;
-static DEFINE_RWLOCK(integrity_iint_lock);
-static struct kmem_cache *iint_cache __ro_after_init;
-
 struct dentry *integrity_dir;
 
-/*
- * __integrity_iint_find - return the iint associated with an inode
- */
-static struct integrity_iint_cache *__integrity_iint_find(struct inode *inode)
-{
-       struct integrity_iint_cache *iint;
-       struct rb_node *n = integrity_iint_tree.rb_node;
-
-       while (n) {
-               iint = rb_entry(n, struct integrity_iint_cache, rb_node);
-
-               if (inode < iint->inode)
-                       n = n->rb_left;
-               else if (inode > iint->inode)
-                       n = n->rb_right;
-               else
-                       return iint;
-       }
-
-       return NULL;
-}
-
-/*
- * integrity_iint_find - return the iint associated with an inode
- */
-struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
-{
-       struct integrity_iint_cache *iint;
-
-       if (!IS_IMA(inode))
-               return NULL;
-
-       read_lock(&integrity_iint_lock);
-       iint = __integrity_iint_find(inode);
-       read_unlock(&integrity_iint_lock);
-
-       return iint;
-}
-
-#define IMA_MAX_NESTING (FILESYSTEM_MAX_STACK_DEPTH+1)
-
-/*
- * It is not clear that IMA should be nested at all, but as long is it measures
- * files both on overlayfs and on underlying fs, we need to annotate the iint
- * mutex to avoid lockdep false positives related to IMA + overlayfs.
- * See ovl_lockdep_annotate_inode_mutex_key() for more details.
- */
-static inline void iint_lockdep_annotate(struct integrity_iint_cache *iint,
-                                        struct inode *inode)
-{
-#ifdef CONFIG_LOCKDEP
-       static struct lock_class_key iint_mutex_key[IMA_MAX_NESTING];
-
-       int depth = inode->i_sb->s_stack_depth;
-
-       if (WARN_ON_ONCE(depth < 0 || depth >= IMA_MAX_NESTING))
-               depth = 0;
-
-       lockdep_set_class(&iint->mutex, &iint_mutex_key[depth]);
-#endif
-}
-
-static void iint_init_always(struct integrity_iint_cache *iint,
-                            struct inode *inode)
-{
-       iint->ima_hash = NULL;
-       iint->version = 0;
-       iint->flags = 0UL;
-       iint->atomic_flags = 0UL;
-       iint->ima_file_status = INTEGRITY_UNKNOWN;
-       iint->ima_mmap_status = INTEGRITY_UNKNOWN;
-       iint->ima_bprm_status = INTEGRITY_UNKNOWN;
-       iint->ima_read_status = INTEGRITY_UNKNOWN;
-       iint->ima_creds_status = INTEGRITY_UNKNOWN;
-       iint->evm_status = INTEGRITY_UNKNOWN;
-       iint->measured_pcrs = 0;
-       mutex_init(&iint->mutex);
-       iint_lockdep_annotate(iint, inode);
-}
-
-static void iint_free(struct integrity_iint_cache *iint)
-{
-       kfree(iint->ima_hash);
-       mutex_destroy(&iint->mutex);
-       kmem_cache_free(iint_cache, iint);
-}
-
-/**
- * integrity_inode_get - find or allocate an iint associated with an inode
- * @inode: pointer to the inode
- * @return: allocated iint
- *
- * Caller must lock i_mutex
- */
-struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
-{
-       struct rb_node **p;
-       struct rb_node *node, *parent = NULL;
-       struct integrity_iint_cache *iint, *test_iint;
-
-       iint = integrity_iint_find(inode);
-       if (iint)
-               return iint;
-
-       iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
-       if (!iint)
-               return NULL;
-
-       iint_init_always(iint, inode);
-
-       write_lock(&integrity_iint_lock);
-
-       p = &integrity_iint_tree.rb_node;
-       while (*p) {
-               parent = *p;
-               test_iint = rb_entry(parent, struct integrity_iint_cache,
-                                    rb_node);
-               if (inode < test_iint->inode) {
-                       p = &(*p)->rb_left;
-               } else if (inode > test_iint->inode) {
-                       p = &(*p)->rb_right;
-               } else {
-                       write_unlock(&integrity_iint_lock);
-                       kmem_cache_free(iint_cache, iint);
-                       return test_iint;
-               }
-       }
-
-       iint->inode = inode;
-       node = &iint->rb_node;
-       inode->i_flags |= S_IMA;
-       rb_link_node(node, parent, p);
-       rb_insert_color(node, &integrity_iint_tree);
-
-       write_unlock(&integrity_iint_lock);
-       return iint;
-}
-
-/**
- * integrity_inode_free - called on security_inode_free
- * @inode: pointer to the inode
- *
- * Free the integrity information(iint) associated with an inode.
- */
-void integrity_inode_free(struct inode *inode)
-{
-       struct integrity_iint_cache *iint;
-
-       if (!IS_IMA(inode))
-               return;
-
-       write_lock(&integrity_iint_lock);
-       iint = __integrity_iint_find(inode);
-       rb_erase(&iint->rb_node, &integrity_iint_tree);
-       write_unlock(&integrity_iint_lock);
-
-       iint_free(iint);
-}
-
-static void iint_init_once(void *foo)
-{
-       struct integrity_iint_cache *iint = (struct integrity_iint_cache *) foo;
-
-       memset(iint, 0, sizeof(*iint));
-}
-
-static int __init integrity_iintcache_init(void)
-{
-       iint_cache =
-           kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache),
-                             0, SLAB_PANIC, iint_init_once);
-       return 0;
-}
-DEFINE_LSM(integrity) = {
-       .name = "integrity",
-       .init = integrity_iintcache_init,
-       .order = LSM_ORDER_LAST,
-};
-
-
 /*
  * integrity_kernel_read - read data from the file
  *
index 671fc50255f908edaffee1a3b5cc2366b415045b..50d6f798e613390270f99427860c0b28608cb7a9 100644 (file)
@@ -102,31 +102,6 @@ struct ima_file_id {
        __u8 hash[HASH_MAX_DIGESTSIZE];
 } __packed;
 
-/* integrity data associated with an inode */
-struct integrity_iint_cache {
-       struct rb_node rb_node; /* rooted in integrity_iint_tree */
-       struct mutex mutex;     /* protects: version, flags, digest */
-       struct inode *inode;    /* back pointer to inode in question */
-       u64 version;            /* track inode changes */
-       unsigned long flags;
-       unsigned long measured_pcrs;
-       unsigned long atomic_flags;
-       unsigned long real_ino;
-       dev_t real_dev;
-       enum integrity_status ima_file_status:4;
-       enum integrity_status ima_mmap_status:4;
-       enum integrity_status ima_bprm_status:4;
-       enum integrity_status ima_read_status:4;
-       enum integrity_status ima_creds_status:4;
-       enum integrity_status evm_status:4;
-       struct ima_digest_data *ima_hash;
-};
-
-/* rbtree tree calls to lookup, insert, delete
- * integrity data associated with an inode.
- */
-struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
-
 int integrity_kernel_read(struct file *file, loff_t offset,
                          void *addr, unsigned long count);
 
index e08c1aa82edf312db5cb82ca759b67238d34e2a2..cbdc9bebe802c529683326359af5e0808ed79cf5 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/kernel.h>
 #include <linux/kernel_read_file.h>
 #include <linux/lsm_hooks.h>
-#include <linux/integrity.h>
 #include <linux/fsnotify.h>
 #include <linux/mman.h>
 #include <linux/mount.h>
@@ -1597,7 +1596,6 @@ static void inode_free_by_rcu(struct rcu_head *head)
  */
 void security_inode_free(struct inode *inode)
 {
-       integrity_inode_free(inode);
        call_void_hook(inode_free_security, inode);
        /*
         * The inode may still be referenced in a path walk and