]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
integrity: IMA hooks
authorMimi Zohar <zohar@linux.vnet.ibm.com>
Wed, 4 Feb 2009 14:06:57 +0000 (09:06 -0500)
committerJames Morris <jmorris@namei.org>
Thu, 5 Feb 2009 22:05:30 +0000 (09:05 +1100)
This patch replaces the generic integrity hooks, for which IMA registered
itself, with IMA integrity hooks in the appropriate places directly
in the fs directory.

Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
Documentation/kernel-parameters.txt
fs/exec.c
fs/file_table.c
fs/inode.c
fs/namei.c
include/linux/ima.h [new file with mode: 0644]
mm/mmap.c

index a2d8805c03d5588f317a9677add758c94051e6a6..7c67b94d1823d03f371f307b5a5dbfacde291578 100644 (file)
@@ -44,6 +44,7 @@ parameter is applicable:
        FB      The frame buffer device is enabled.
        HW      Appropriate hardware is enabled.
        IA-64   IA-64 architecture is enabled.
+       IMA     Integrity measurement architecture is enabled.
        IOSCHED More than one I/O scheduler is enabled.
        IP_PNP  IP DHCP, BOOTP, or RARP is enabled.
        ISAPNP  ISA PnP code is enabled.
index 02d2e120542d76ca26ee233e638749e53bc227f0..9c789a525cc419fbadad01e192821878f57d9d14 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -45,6 +45,7 @@
 #include <linux/proc_fs.h>
 #include <linux/mount.h>
 #include <linux/security.h>
+#include <linux/ima.h>
 #include <linux/syscalls.h>
 #include <linux/tsacct_kern.h>
 #include <linux/cn_proc.h>
@@ -128,6 +129,9 @@ asmlinkage long sys_uselib(const char __user * library)
                goto exit;
 
        error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN);
+       if (error)
+               goto exit;
+       error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN);
        if (error)
                goto exit;
 
@@ -681,6 +685,9 @@ struct file *open_exec(const char *name)
                goto out_path_put;
 
        err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN);
+       if (err)
+               goto out_path_put;
+       err = ima_path_check(&nd.path, MAY_EXEC | MAY_OPEN);
        if (err)
                goto out_path_put;
 
@@ -1207,6 +1214,9 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
        }
 #endif
        retval = security_bprm_check(bprm);
+       if (retval)
+               return retval;
+       retval = ima_bprm_check(bprm);
        if (retval)
                return retval;
 
index 0fbcacc3ea754a01e92e2529f7955ea1fcf08c13..55895ccc08c6eadb8b51404bc7ef91f5ed0bcb18 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/security.h>
+#include <linux/ima.h>
 #include <linux/eventpoll.h>
 #include <linux/rcupdate.h>
 #include <linux/mount.h>
@@ -276,6 +277,7 @@ void __fput(struct file *file)
        if (file->f_op && file->f_op->release)
                file->f_op->release(inode, file);
        security_file_free(file);
+       ima_file_free(file);
        if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL))
                cdev_put(inode->i_cdev);
        fops_put(file->f_op);
index 098a2443196f20cacd3c1a4c38964646a14c6e74..ed22b14f22025aaf00ca39412b523cb30bd2a5bd 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/hash.h>
 #include <linux/swap.h>
 #include <linux/security.h>
+#include <linux/ima.h>
 #include <linux/pagemap.h>
 #include <linux/cdev.h>
 #include <linux/bootmem.h>
@@ -144,13 +145,13 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
        inode->i_cdev = NULL;
        inode->i_rdev = 0;
        inode->dirtied_when = 0;
-       if (security_inode_alloc(inode)) {
-               if (inode->i_sb->s_op->destroy_inode)
-                       inode->i_sb->s_op->destroy_inode(inode);
-               else
-                       kmem_cache_free(inode_cachep, (inode));
-               return NULL;
-       }
+
+       if (security_inode_alloc(inode))
+               goto out_free_inode;
+
+       /* allocate and initialize an i_integrity */
+       if (ima_inode_alloc(inode))
+               goto out_free_security;
 
        spin_lock_init(&inode->i_lock);
        lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key);
@@ -186,6 +187,15 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
        inode->i_mapping = mapping;
 
        return inode;
+
+out_free_security:
+       security_inode_free(inode);
+out_free_inode:
+       if (inode->i_sb->s_op->destroy_inode)
+               inode->i_sb->s_op->destroy_inode(inode);
+       else
+               kmem_cache_free(inode_cachep, (inode));
+       return NULL;
 }
 EXPORT_SYMBOL(inode_init_always);
 
index af3783fff1de66ee922411dac7d5ad92811291d7..734f2b5591bf9758aedc875381a9456fe7853929 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/fsnotify.h>
 #include <linux/personality.h>
 #include <linux/security.h>
+#include <linux/ima.h>
 #include <linux/syscalls.h>
 #include <linux/mount.h>
 #include <linux/audit.h>
@@ -860,6 +861,8 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
                err = exec_permission_lite(inode);
                if (err == -EAGAIN)
                        err = vfs_permission(nd, MAY_EXEC);
+               if (!err)
+                       err = ima_path_check(&nd->path, MAY_EXEC);
                if (err)
                        break;
 
@@ -1525,6 +1528,11 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
        error = vfs_permission(nd, acc_mode);
        if (error)
                return error;
+
+       error = ima_path_check(&nd->path,
+                              acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC));
+       if (error)
+               return error;
        /*
         * An append-only file must be opened in append mode for writing.
         */
diff --git a/include/linux/ima.h b/include/linux/ima.h
new file mode 100644 (file)
index 0000000..4ed1e4d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 IBM Corporation
+ * Author: Mimi Zohar <zohar@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+#include <linux/fs.h>
+
+#ifndef _LINUX_IMA_H
+#define _LINUX_IMA_H
+
+static inline int ima_bprm_check(struct linux_binprm *bprm)
+{
+       return 0;
+}
+
+static inline int ima_inode_alloc(struct inode *inode)
+{
+       return 0;
+}
+
+static inline void ima_inode_free(struct inode *inode)
+{
+       return;
+}
+
+static inline int ima_path_check(struct path *path, int mask)
+{
+       return 0;
+}
+
+static inline void ima_file_free(struct file *file)
+{
+       return;
+}
+
+static inline int ima_file_mmap(struct file *file, unsigned long prot)
+{
+       return 0;
+}
+#endif /* _LINUX_IMA_H */
index d4855a682ab622863f85352a5353bd45fa1440e4..c3647f3b06216e6280a9e48a25ba8b68f4e1ce5f 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -20,6 +20,7 @@
 #include <linux/fs.h>
 #include <linux/personality.h>
 #include <linux/security.h>
+#include <linux/ima.h>
 #include <linux/hugetlb.h>
 #include <linux/profile.h>
 #include <linux/module.h>
@@ -1048,6 +1049,9 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
        }
 
        error = security_file_mmap(file, reqprot, prot, flags, addr, 0);
+       if (error)
+               return error;
+       error = ima_file_mmap(file, prot);
        if (error)
                return error;