aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/evm23
-rw-r--r--Documentation/kernel-parameters.txt6
-rw-r--r--fs/attr.c5
-rw-r--r--fs/btrfs/xattr.c50
-rw-r--r--fs/ext2/xattr_security.c34
-rw-r--r--fs/ext3/xattr_security.c36
-rw-r--r--fs/ext4/xattr_security.c36
-rw-r--r--fs/gfs2/inode.c38
-rw-r--r--fs/jffs2/security.c35
-rw-r--r--fs/jfs/xattr.c57
-rw-r--r--fs/ocfs2/xattr.c38
-rw-r--r--fs/reiserfs/xattr_security.c4
-rw-r--r--fs/xattr.c63
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c39
-rw-r--r--include/linux/evm.h92
-rw-r--r--include/linux/ima.h13
-rw-r--r--include/linux/integrity.h38
-rw-r--r--include/linux/security.h17
-rw-r--r--include/linux/xattr.h14
-rw-r--r--mm/shmem.c4
-rw-r--r--security/Kconfig2
-rw-r--r--security/Makefile4
-rw-r--r--security/integrity/Kconfig7
-rw-r--r--security/integrity/Makefile12
-rw-r--r--security/integrity/evm/Kconfig12
-rw-r--r--security/integrity/evm/Makefile6
-rw-r--r--security/integrity/evm/evm.h38
-rw-r--r--security/integrity/evm/evm_crypto.c216
-rw-r--r--security/integrity/evm/evm_main.c384
-rw-r--r--security/integrity/evm/evm_secfs.c108
-rw-r--r--security/integrity/iint.c171
-rw-r--r--security/integrity/ima/Kconfig1
-rw-r--r--security/integrity/ima/Makefile2
-rw-r--r--security/integrity/ima/ima.h29
-rw-r--r--security/integrity/ima/ima_api.c7
-rw-r--r--security/integrity/ima/ima_iint.c169
-rw-r--r--security/integrity/ima/ima_main.c12
-rw-r--r--security/integrity/integrity.h47
-rw-r--r--security/security.c71
39 files changed, 1535 insertions, 405 deletions
diff --git a/Documentation/ABI/testing/evm b/Documentation/ABI/testing/evm
new file mode 100644
index 000000000000..8374d4557e5d
--- /dev/null
+++ b/Documentation/ABI/testing/evm
@@ -0,0 +1,23 @@
1What: security/evm
2Date: March 2011
3Contact: Mimi Zohar <zohar@us.ibm.com>
4Description:
5 EVM protects a file's security extended attributes(xattrs)
6 against integrity attacks. The initial method maintains an
7 HMAC-sha1 value across the extended attributes, storing the
8 value as the extended attribute 'security.evm'.
9
10 EVM depends on the Kernel Key Retention System to provide it
11 with a trusted/encrypted key for the HMAC-sha1 operation.
12 The key is loaded onto the root's keyring using keyctl. Until
13 EVM receives notification that the key has been successfully
14 loaded onto the keyring (echo 1 > <securityfs>/evm), EVM
15 can not create or validate the 'security.evm' xattr, but
16 returns INTEGRITY_UNKNOWN. Loading the key and signaling EVM
17 should be done as early as possible. Normally this is done
18 in the initramfs, which has already been measured as part
19 of the trusted boot. For more information on creating and
20 loading existing trusted/encrypted keys, refer to:
21 Documentation/keys-trusted-encrypted.txt. (A sample dracut
22 patch, which loads the trusted/encrypted key and enables
23 EVM, is available from http://linux-ima.sourceforge.net/#EVM.)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index e279b7242912..cd7c86110147 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -48,6 +48,7 @@ parameter is applicable:
48 EDD BIOS Enhanced Disk Drive Services (EDD) is enabled 48 EDD BIOS Enhanced Disk Drive Services (EDD) is enabled
49 EFI EFI Partitioning (GPT) is enabled 49 EFI EFI Partitioning (GPT) is enabled
50 EIDE EIDE/ATAPI support is enabled. 50 EIDE EIDE/ATAPI support is enabled.
51 EVM Extended Verification Module
51 FB The frame buffer device is enabled. 52 FB The frame buffer device is enabled.
52 GCOV GCOV profiling is enabled. 53 GCOV GCOV profiling is enabled.
53 HW Appropriate hardware is enabled. 54 HW Appropriate hardware is enabled.
@@ -758,6 +759,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
758 This option is obsoleted by the "netdev=" option, which 759 This option is obsoleted by the "netdev=" option, which
759 has equivalent usage. See its documentation for details. 760 has equivalent usage. See its documentation for details.
760 761
762 evm= [EVM]
763 Format: { "fix" }
764 Permit 'security.evm' to be updated regardless of
765 current integrity status.
766
761 failslab= 767 failslab=
762 fail_page_alloc= 768 fail_page_alloc=
763 fail_make_request=[KNL] 769 fail_make_request=[KNL]
diff --git a/fs/attr.c b/fs/attr.c
index 538e27959d3f..7ee7ba488313 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -13,6 +13,7 @@
13#include <linux/fsnotify.h> 13#include <linux/fsnotify.h>
14#include <linux/fcntl.h> 14#include <linux/fcntl.h>
15#include <linux/security.h> 15#include <linux/security.h>
16#include <linux/evm.h>
16 17
17/** 18/**
18 * inode_change_ok - check if attribute changes to an inode are allowed 19 * inode_change_ok - check if attribute changes to an inode are allowed
@@ -237,8 +238,10 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
237 else 238 else
238 error = simple_setattr(dentry, attr); 239 error = simple_setattr(dentry, attr);
239 240
240 if (!error) 241 if (!error) {
241 fsnotify_change(dentry, ia_valid); 242 fsnotify_change(dentry, ia_valid);
243 evm_inode_post_setattr(dentry, ia_valid);
244 }
242 245
243 return error; 246 return error;
244} 247}
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index d733b9cfea34..6196e1a76c14 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -374,36 +374,36 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
374 XATTR_REPLACE); 374 XATTR_REPLACE);
375} 375}
376 376
377int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, 377int btrfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
378 struct inode *inode, struct inode *dir, 378 void *fs_info)
379 const struct qstr *qstr)
380{ 379{
381 int err; 380 const struct xattr *xattr;
382 size_t len; 381 struct btrfs_trans_handle *trans = fs_info;
383 void *value;
384 char *suffix;
385 char *name; 382 char *name;
383 int err = 0;
386 384
387 err = security_inode_init_security(inode, dir, qstr, &suffix, &value, 385 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
388 &len); 386 name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
389 if (err) { 387 strlen(xattr->name) + 1, GFP_NOFS);
390 if (err == -EOPNOTSUPP) 388 if (!name) {
391 return 0; 389 err = -ENOMEM;
392 return err; 390 break;
393 } 391 }
394
395 name = kmalloc(XATTR_SECURITY_PREFIX_LEN + strlen(suffix) + 1,
396 GFP_NOFS);
397 if (!name) {
398 err = -ENOMEM;
399 } else {
400 strcpy(name, XATTR_SECURITY_PREFIX); 392 strcpy(name, XATTR_SECURITY_PREFIX);
401 strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); 393 strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
402 err = __btrfs_setxattr(trans, inode, name, value, len, 0); 394 err = __btrfs_setxattr(trans, inode, name,
395 xattr->value, xattr->value_len, 0);
403 kfree(name); 396 kfree(name);
397 if (err < 0)
398 break;
404 } 399 }
405
406 kfree(suffix);
407 kfree(value);
408 return err; 400 return err;
409} 401}
402
403int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
404 struct inode *inode, struct inode *dir,
405 const struct qstr *qstr)
406{
407 return security_inode_init_security(inode, dir, qstr,
408 &btrfs_initxattrs, trans);
409}
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c
index 5d979b4347b0..c922adc8ef41 100644
--- a/fs/ext2/xattr_security.c
+++ b/fs/ext2/xattr_security.c
@@ -46,28 +46,30 @@ ext2_xattr_security_set(struct dentry *dentry, const char *name,
46 value, size, flags); 46 value, size, flags);
47} 47}
48 48
49int 49int ext2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
50ext2_init_security(struct inode *inode, struct inode *dir, 50 void *fs_info)
51 const struct qstr *qstr)
52{ 51{
53 int err; 52 const struct xattr *xattr;
54 size_t len; 53 int err = 0;
55 void *value;
56 char *name;
57 54
58 err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 55 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
59 if (err) { 56 err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
60 if (err == -EOPNOTSUPP) 57 xattr->name, xattr->value,
61 return 0; 58 xattr->value_len, 0);
62 return err; 59 if (err < 0)
60 break;
63 } 61 }
64 err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
65 name, value, len, 0);
66 kfree(name);
67 kfree(value);
68 return err; 62 return err;
69} 63}
70 64
65int
66ext2_init_security(struct inode *inode, struct inode *dir,
67 const struct qstr *qstr)
68{
69 return security_inode_init_security(inode, dir, qstr,
70 &ext2_initxattrs, NULL);
71}
72
71const struct xattr_handler ext2_xattr_security_handler = { 73const struct xattr_handler ext2_xattr_security_handler = {
72 .prefix = XATTR_SECURITY_PREFIX, 74 .prefix = XATTR_SECURITY_PREFIX,
73 .list = ext2_xattr_security_list, 75 .list = ext2_xattr_security_list,
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c
index b8d9f83aa5c5..3c218b8a51d4 100644
--- a/fs/ext3/xattr_security.c
+++ b/fs/ext3/xattr_security.c
@@ -48,28 +48,32 @@ ext3_xattr_security_set(struct dentry *dentry, const char *name,
48 name, value, size, flags); 48 name, value, size, flags);
49} 49}
50 50
51int 51int ext3_initxattrs(struct inode *inode, const struct xattr *xattr_array,
52ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir, 52 void *fs_info)
53 const struct qstr *qstr)
54{ 53{
55 int err; 54 const struct xattr *xattr;
56 size_t len; 55 handle_t *handle = fs_info;
57 void *value; 56 int err = 0;
58 char *name;
59 57
60 err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 58 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
61 if (err) { 59 err = ext3_xattr_set_handle(handle, inode,
62 if (err == -EOPNOTSUPP) 60 EXT3_XATTR_INDEX_SECURITY,
63 return 0; 61 xattr->name, xattr->value,
64 return err; 62 xattr->value_len, 0);
63 if (err < 0)
64 break;
65 } 65 }
66 err = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_SECURITY,
67 name, value, len, 0);
68 kfree(name);
69 kfree(value);
70 return err; 66 return err;
71} 67}
72 68
69int
70ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
71 const struct qstr *qstr)
72{
73 return security_inode_init_security(inode, dir, qstr,
74 &ext3_initxattrs, handle);
75}
76
73const struct xattr_handler ext3_xattr_security_handler = { 77const struct xattr_handler ext3_xattr_security_handler = {
74 .prefix = XATTR_SECURITY_PREFIX, 78 .prefix = XATTR_SECURITY_PREFIX,
75 .list = ext3_xattr_security_list, 79 .list = ext3_xattr_security_list,
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
index 007c3bfbf094..34e4350dd4d9 100644
--- a/fs/ext4/xattr_security.c
+++ b/fs/ext4/xattr_security.c
@@ -48,28 +48,32 @@ ext4_xattr_security_set(struct dentry *dentry, const char *name,
48 name, value, size, flags); 48 name, value, size, flags);
49} 49}
50 50
51int 51int ext4_initxattrs(struct inode *inode, const struct xattr *xattr_array,
52ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir, 52 void *fs_info)
53 const struct qstr *qstr)
54{ 53{
55 int err; 54 const struct xattr *xattr;
56 size_t len; 55 handle_t *handle = fs_info;
57 void *value; 56 int err = 0;
58 char *name;
59 57
60 err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 58 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
61 if (err) { 59 err = ext4_xattr_set_handle(handle, inode,
62 if (err == -EOPNOTSUPP) 60 EXT4_XATTR_INDEX_SECURITY,
63 return 0; 61 xattr->name, xattr->value,
64 return err; 62 xattr->value_len, 0);
63 if (err < 0)
64 break;
65 } 65 }
66 err = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_SECURITY,
67 name, value, len, 0);
68 kfree(name);
69 kfree(value);
70 return err; 66 return err;
71} 67}
72 68
69int
70ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
71 const struct qstr *qstr)
72{
73 return security_inode_init_security(inode, dir, qstr,
74 &ext4_initxattrs, handle);
75}
76
73const struct xattr_handler ext4_xattr_security_handler = { 77const struct xattr_handler ext4_xattr_security_handler = {
74 .prefix = XATTR_SECURITY_PREFIX, 78 .prefix = XATTR_SECURITY_PREFIX,
75 .list = ext4_xattr_security_list, 79 .list = ext4_xattr_security_list,
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 900cf986aadc..6525b804d5ec 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -624,31 +624,29 @@ fail:
624 return error; 624 return error;
625} 625}
626 626
627static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip, 627int gfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
628 const struct qstr *qstr) 628 void *fs_info)
629{ 629{
630 int err; 630 const struct xattr *xattr;
631 size_t len; 631 int err = 0;
632 void *value; 632
633 char *name; 633 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
634 634 err = __gfs2_xattr_set(inode, xattr->name, xattr->value,
635 err = security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr, 635 xattr->value_len, 0,
636 &name, &value, &len); 636 GFS2_EATYPE_SECURITY);
637 637 if (err < 0)
638 if (err) { 638 break;
639 if (err == -EOPNOTSUPP)
640 return 0;
641 return err;
642 } 639 }
643
644 err = __gfs2_xattr_set(&ip->i_inode, name, value, len, 0,
645 GFS2_EATYPE_SECURITY);
646 kfree(value);
647 kfree(name);
648
649 return err; 640 return err;
650} 641}
651 642
643static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
644 const struct qstr *qstr)
645{
646 return security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr,
647 &gfs2_initxattrs, NULL);
648}
649
652/** 650/**
653 * gfs2_create_inode - Create a new inode 651 * gfs2_create_inode - Create a new inode
654 * @dir: The parent directory 652 * @dir: The parent directory
diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c
index cfeb7164b085..0f20208df602 100644
--- a/fs/jffs2/security.c
+++ b/fs/jffs2/security.c
@@ -22,26 +22,29 @@
22#include <linux/security.h> 22#include <linux/security.h>
23#include "nodelist.h" 23#include "nodelist.h"
24 24
25/* ---- Initial Security Label Attachment -------------- */ 25/* ---- Initial Security Label(s) Attachment callback --- */
26int jffs2_init_security(struct inode *inode, struct inode *dir, 26int jffs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
27 const struct qstr *qstr) 27 void *fs_info)
28{ 28{
29 int rc; 29 const struct xattr *xattr;
30 size_t len; 30 int err = 0;
31 void *value;
32 char *name;
33 31
34 rc = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 32 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
35 if (rc) { 33 err = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY,
36 if (rc == -EOPNOTSUPP) 34 xattr->name, xattr->value,
37 return 0; 35 xattr->value_len, 0);
38 return rc; 36 if (err < 0)
37 break;
39 } 38 }
40 rc = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, value, len, 0); 39 return err;
40}
41 41
42 kfree(name); 42/* ---- Initial Security Label(s) Attachment ----------- */
43 kfree(value); 43int jffs2_init_security(struct inode *inode, struct inode *dir,
44 return rc; 44 const struct qstr *qstr)
45{
46 return security_inode_init_security(inode, dir, qstr,
47 &jffs2_initxattrs, NULL);
45} 48}
46 49
47/* ---- XATTR Handler for "security.*" ----------------- */ 50/* ---- XATTR Handler for "security.*" ----------------- */
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index e87fedef23db..26683e15b3ac 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -1089,38 +1089,37 @@ int jfs_removexattr(struct dentry *dentry, const char *name)
1089} 1089}
1090 1090
1091#ifdef CONFIG_JFS_SECURITY 1091#ifdef CONFIG_JFS_SECURITY
1092int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir, 1092int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
1093 const struct qstr *qstr) 1093 void *fs_info)
1094{ 1094{
1095 int rc; 1095 const struct xattr *xattr;
1096 size_t len; 1096 tid_t *tid = fs_info;
1097 void *value;
1098 char *suffix;
1099 char *name; 1097 char *name;
1100 1098 int err = 0;
1101 rc = security_inode_init_security(inode, dir, qstr, &suffix, &value, 1099
1102 &len); 1100 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
1103 if (rc) { 1101 name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
1104 if (rc == -EOPNOTSUPP) 1102 strlen(xattr->name) + 1, GFP_NOFS);
1105 return 0; 1103 if (!name) {
1106 return rc; 1104 err = -ENOMEM;
1107 } 1105 break;
1108 name = kmalloc(XATTR_SECURITY_PREFIX_LEN + 1 + strlen(suffix), 1106 }
1109 GFP_NOFS); 1107 strcpy(name, XATTR_SECURITY_PREFIX);
1110 if (!name) { 1108 strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
1111 rc = -ENOMEM; 1109
1112 goto kmalloc_failed; 1110 err = __jfs_setxattr(*tid, inode, name,
1111 xattr->value, xattr->value_len, 0);
1112 kfree(name);
1113 if (err < 0)
1114 break;
1113 } 1115 }
1114 strcpy(name, XATTR_SECURITY_PREFIX); 1116 return err;
1115 strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); 1117}
1116
1117 rc = __jfs_setxattr(tid, inode, name, value, len, 0);
1118
1119 kfree(name);
1120kmalloc_failed:
1121 kfree(suffix);
1122 kfree(value);
1123 1118
1124 return rc; 1119int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir,
1120 const struct qstr *qstr)
1121{
1122 return security_inode_init_security(inode, dir, qstr,
1123 &jfs_initxattrs, &tid);
1125} 1124}
1126#endif 1125#endif
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 81ecf9c0bf0a..194fb22ef79d 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -7185,20 +7185,9 @@ int ocfs2_init_security_and_acl(struct inode *dir,
7185{ 7185{
7186 int ret = 0; 7186 int ret = 0;
7187 struct buffer_head *dir_bh = NULL; 7187 struct buffer_head *dir_bh = NULL;
7188 struct ocfs2_security_xattr_info si = {
7189 .enable = 1,
7190 };
7191 7188
7192 ret = ocfs2_init_security_get(inode, dir, qstr, &si); 7189 ret = ocfs2_init_security_get(inode, dir, qstr, NULL);
7193 if (!ret) { 7190 if (!ret) {
7194 ret = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
7195 si.name, si.value, si.value_len,
7196 XATTR_CREATE);
7197 if (ret) {
7198 mlog_errno(ret);
7199 goto leave;
7200 }
7201 } else if (ret != -EOPNOTSUPP) {
7202 mlog_errno(ret); 7191 mlog_errno(ret);
7203 goto leave; 7192 goto leave;
7204 } 7193 }
@@ -7255,6 +7244,22 @@ static int ocfs2_xattr_security_set(struct dentry *dentry, const char *name,
7255 name, value, size, flags); 7244 name, value, size, flags);
7256} 7245}
7257 7246
7247int ocfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
7248 void *fs_info)
7249{
7250 const struct xattr *xattr;
7251 int err = 0;
7252
7253 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
7254 err = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
7255 xattr->name, xattr->value,
7256 xattr->value_len, XATTR_CREATE);
7257 if (err)
7258 break;
7259 }
7260 return err;
7261}
7262
7258int ocfs2_init_security_get(struct inode *inode, 7263int ocfs2_init_security_get(struct inode *inode,
7259 struct inode *dir, 7264 struct inode *dir,
7260 const struct qstr *qstr, 7265 const struct qstr *qstr,
@@ -7263,8 +7268,13 @@ int ocfs2_init_security_get(struct inode *inode,
7263 /* check whether ocfs2 support feature xattr */ 7268 /* check whether ocfs2 support feature xattr */
7264 if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb))) 7269 if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb)))
7265 return -EOPNOTSUPP; 7270 return -EOPNOTSUPP;
7266 return security_inode_init_security(inode, dir, qstr, &si->name, 7271 if (si)
7267 &si->value, &si->value_len); 7272 return security_old_inode_init_security(inode, dir, qstr,
7273 &si->name, &si->value,
7274 &si->value_len);
7275
7276 return security_inode_init_security(inode, dir, qstr,
7277 &ocfs2_initxattrs, NULL);
7268} 7278}
7269 7279
7270int ocfs2_init_security_set(handle_t *handle, 7280int ocfs2_init_security_set(handle_t *handle,
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
index ef66c18a9332..534668fa41be 100644
--- a/fs/reiserfs/xattr_security.c
+++ b/fs/reiserfs/xattr_security.c
@@ -66,8 +66,8 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
66 if (IS_PRIVATE(dir)) 66 if (IS_PRIVATE(dir))
67 return 0; 67 return 0;
68 68
69 error = security_inode_init_security(inode, dir, qstr, &sec->name, 69 error = security_old_inode_init_security(inode, dir, qstr, &sec->name,
70 &sec->value, &sec->length); 70 &sec->value, &sec->length);
71 if (error) { 71 if (error) {
72 if (error == -EOPNOTSUPP) 72 if (error == -EOPNOTSUPP)
73 error = 0; 73 error = 0;
diff --git a/fs/xattr.c b/fs/xattr.c
index f060663ab70c..67583de8218c 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -14,6 +14,7 @@
14#include <linux/mount.h> 14#include <linux/mount.h>
15#include <linux/namei.h> 15#include <linux/namei.h>
16#include <linux/security.h> 16#include <linux/security.h>
17#include <linux/evm.h>
17#include <linux/syscalls.h> 18#include <linux/syscalls.h>
18#include <linux/module.h> 19#include <linux/module.h>
19#include <linux/fsnotify.h> 20#include <linux/fsnotify.h>
@@ -166,6 +167,64 @@ out_noalloc:
166} 167}
167EXPORT_SYMBOL_GPL(xattr_getsecurity); 168EXPORT_SYMBOL_GPL(xattr_getsecurity);
168 169
170/*
171 * vfs_getxattr_alloc - allocate memory, if necessary, before calling getxattr
172 *
173 * Allocate memory, if not already allocated, or re-allocate correct size,
174 * before retrieving the extended attribute.
175 *
176 * Returns the result of alloc, if failed, or the getxattr operation.
177 */
178ssize_t
179vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
180 size_t xattr_size, gfp_t flags)
181{
182 struct inode *inode = dentry->d_inode;
183 char *value = *xattr_value;
184 int error;
185
186 error = xattr_permission(inode, name, MAY_READ);
187 if (error)
188 return error;
189
190 if (!inode->i_op->getxattr)
191 return -EOPNOTSUPP;
192
193 error = inode->i_op->getxattr(dentry, name, NULL, 0);
194 if (error < 0)
195 return error;
196
197 if (!value || (error > xattr_size)) {
198 value = krealloc(*xattr_value, error + 1, flags);
199 if (!value)
200 return -ENOMEM;
201 memset(value, 0, error + 1);
202 }
203
204 error = inode->i_op->getxattr(dentry, name, value, error);
205 *xattr_value = value;
206 return error;
207}
208
209/* Compare an extended attribute value with the given value */
210int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
211 const char *value, size_t size, gfp_t flags)
212{
213 char *xattr_value = NULL;
214 int rc;
215
216 rc = vfs_getxattr_alloc(dentry, xattr_name, &xattr_value, 0, flags);
217 if (rc < 0)
218 return rc;
219
220 if ((rc != size) || (memcmp(xattr_value, value, rc) != 0))
221 rc = -EINVAL;
222 else
223 rc = 0;
224 kfree(xattr_value);
225 return rc;
226}
227
169ssize_t 228ssize_t
170vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) 229vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
171{ 230{
@@ -243,8 +302,10 @@ vfs_removexattr(struct dentry *dentry, const char *name)
243 error = inode->i_op->removexattr(dentry, name); 302 error = inode->i_op->removexattr(dentry, name);
244 mutex_unlock(&inode->i_mutex); 303 mutex_unlock(&inode->i_mutex);
245 304
246 if (!error) 305 if (!error) {
247 fsnotify_xattr(dentry); 306 fsnotify_xattr(dentry);
307 evm_inode_post_removexattr(dentry, name);
308 }
248 return error; 309 return error;
249} 310}
250EXPORT_SYMBOL_GPL(vfs_removexattr); 311EXPORT_SYMBOL_GPL(vfs_removexattr);
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index b9c172b3fbbe..37194607162d 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -94,37 +94,38 @@ xfs_mark_inode_dirty(
94 mark_inode_dirty(inode); 94 mark_inode_dirty(inode);
95} 95}
96 96
97
98int xfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
99 void *fs_info)
100{
101 const struct xattr *xattr;
102 struct xfs_inode *ip = XFS_I(inode);
103 int error = 0;
104
105 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
106 error = xfs_attr_set(ip, xattr->name, xattr->value,
107 xattr->value_len, ATTR_SECURE);
108 if (error < 0)
109 break;
110 }
111 return error;
112}
113
97/* 114/*
98 * Hook in SELinux. This is not quite correct yet, what we really need 115 * Hook in SELinux. This is not quite correct yet, what we really need
99 * here (as we do for default ACLs) is a mechanism by which creation of 116 * here (as we do for default ACLs) is a mechanism by which creation of
100 * these attrs can be journalled at inode creation time (along with the 117 * these attrs can be journalled at inode creation time (along with the
101 * inode, of course, such that log replay can't cause these to be lost). 118 * inode, of course, such that log replay can't cause these to be lost).
102 */ 119 */
120
103STATIC int 121STATIC int
104xfs_init_security( 122xfs_init_security(
105 struct inode *inode, 123 struct inode *inode,
106 struct inode *dir, 124 struct inode *dir,
107 const struct qstr *qstr) 125 const struct qstr *qstr)
108{ 126{
109 struct xfs_inode *ip = XFS_I(inode); 127 return security_inode_init_security(inode, dir, qstr,
110 size_t length; 128 &xfs_initxattrs, NULL);
111 void *value;
112 unsigned char *name;
113 int error;
114
115 error = security_inode_init_security(inode, dir, qstr, (char **)&name,
116 &value, &length);
117 if (error) {
118 if (error == -EOPNOTSUPP)
119 return 0;
120 return -error;
121 }
122
123 error = xfs_attr_set(ip, name, value, length, ATTR_SECURE);
124
125 kfree(name);
126 kfree(value);
127 return error;
128} 129}
129 130
130static void 131static void
diff --git a/include/linux/evm.h b/include/linux/evm.h
new file mode 100644
index 000000000000..db5556dcdd27
--- /dev/null
+++ b/include/linux/evm.h
@@ -0,0 +1,92 @@
1/*
2 * evm.h
3 *
4 * Copyright (c) 2009 IBM Corporation
5 * Author: Mimi Zohar <zohar@us.ibm.com>
6 */
7
8#ifndef _LINUX_EVM_H
9#define _LINUX_EVM_H
10
11#include <linux/integrity.h>
12#include <linux/xattr.h>
13
14struct integrity_iint_cache;
15
16#ifdef CONFIG_EVM
17extern enum integrity_status evm_verifyxattr(struct dentry *dentry,
18 const char *xattr_name,
19 void *xattr_value,
20 size_t xattr_value_len,
21 struct integrity_iint_cache *iint);
22extern int evm_inode_setattr(struct dentry *dentry, struct iattr *attr);
23extern void evm_inode_post_setattr(struct dentry *dentry, int ia_valid);
24extern int evm_inode_setxattr(struct dentry *dentry, const char *name,
25 const void *value, size_t size);
26extern void evm_inode_post_setxattr(struct dentry *dentry,
27 const char *xattr_name,
28 const void *xattr_value,
29 size_t xattr_value_len);
30extern int evm_inode_removexattr(struct dentry *dentry, const char *xattr_name);
31extern void evm_inode_post_removexattr(struct dentry *dentry,
32 const char *xattr_name);
33extern int evm_inode_init_security(struct inode *inode,
34 const struct xattr *xattr_array,
35 struct xattr *evm);
36#else
37#ifdef CONFIG_INTEGRITY
38static inline enum integrity_status evm_verifyxattr(struct dentry *dentry,
39 const char *xattr_name,
40 void *xattr_value,
41 size_t xattr_value_len,
42 struct integrity_iint_cache *iint)
43{
44 return INTEGRITY_UNKNOWN;
45}
46#endif
47
48static int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
49{
50 return 0;
51}
52
53static inline void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
54{
55 return;
56}
57
58static inline int evm_inode_setxattr(struct dentry *dentry, const char *name,
59 const void *value, size_t size)
60{
61 return 0;
62}
63
64static inline void evm_inode_post_setxattr(struct dentry *dentry,
65 const char *xattr_name,
66 const void *xattr_value,
67 size_t xattr_value_len)
68{
69 return;
70}
71
72static inline int evm_inode_removexattr(struct dentry *dentry,
73 const char *xattr_name)
74{
75 return 0;
76}
77
78static inline void evm_inode_post_removexattr(struct dentry *dentry,
79 const char *xattr_name)
80{
81 return;
82}
83
84static inline int evm_inode_init_security(struct inode *inode,
85 const struct xattr *xattr_array,
86 struct xattr *evm)
87{
88 return -EOPNOTSUPP;
89}
90
91#endif /* CONFIG_EVM_H */
92#endif /* LINUX_EVM_H */
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 09e6e62f9953..6ac8e50c6cf5 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -15,8 +15,6 @@ struct linux_binprm;
15 15
16#ifdef CONFIG_IMA 16#ifdef CONFIG_IMA
17extern int ima_bprm_check(struct linux_binprm *bprm); 17extern int ima_bprm_check(struct linux_binprm *bprm);
18extern int ima_inode_alloc(struct inode *inode);
19extern void ima_inode_free(struct inode *inode);
20extern int ima_file_check(struct file *file, int mask); 18extern int ima_file_check(struct file *file, int mask);
21extern void ima_file_free(struct file *file); 19extern void ima_file_free(struct file *file);
22extern int ima_file_mmap(struct file *file, unsigned long prot); 20extern int ima_file_mmap(struct file *file, unsigned long prot);
@@ -27,16 +25,6 @@ static inline int ima_bprm_check(struct linux_binprm *bprm)
27 return 0; 25 return 0;
28} 26}
29 27
30static inline int ima_inode_alloc(struct inode *inode)
31{
32 return 0;
33}
34
35static inline void ima_inode_free(struct inode *inode)
36{
37 return;
38}
39
40static inline int ima_file_check(struct file *file, int mask) 28static inline int ima_file_check(struct file *file, int mask)
41{ 29{
42 return 0; 30 return 0;
@@ -51,6 +39,5 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
51{ 39{
52 return 0; 40 return 0;
53} 41}
54
55#endif /* CONFIG_IMA_H */ 42#endif /* CONFIG_IMA_H */
56#endif /* _LINUX_IMA_H */ 43#endif /* _LINUX_IMA_H */
diff --git a/include/linux/integrity.h b/include/linux/integrity.h
new file mode 100644
index 000000000000..968443385678
--- /dev/null
+++ b/include/linux/integrity.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright (C) 2009 IBM Corporation
3 * Author: Mimi Zohar <zohar@us.ibm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 2 of the License.
8 */
9
10#ifndef _LINUX_INTEGRITY_H
11#define _LINUX_INTEGRITY_H
12
13#include <linux/fs.h>
14
15enum integrity_status {
16 INTEGRITY_PASS = 0,
17 INTEGRITY_FAIL,
18 INTEGRITY_NOLABEL,
19 INTEGRITY_UNKNOWN,
20};
21
22/* List of EVM protected security xattrs */
23#ifdef CONFIG_INTEGRITY
24extern int integrity_inode_alloc(struct inode *inode);
25extern void integrity_inode_free(struct inode *inode);
26
27#else
28static inline int integrity_inode_alloc(struct inode *inode)
29{
30 return 0;
31}
32
33static inline void integrity_inode_free(struct inode *inode)
34{
35 return;
36}
37#endif /* CONFIG_INTEGRITY_H */
38#endif /* _LINUX_INTEGRITY_H */
diff --git a/include/linux/security.h b/include/linux/security.h
index ebd2a53a3d07..1c528b19a329 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -36,6 +36,7 @@
36#include <linux/key.h> 36#include <linux/key.h>
37#include <linux/xfrm.h> 37#include <linux/xfrm.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/xattr.h>
39#include <net/flow.h> 40#include <net/flow.h>
40 41
41/* Maximum number of letters for an LSM name string */ 42/* Maximum number of letters for an LSM name string */
@@ -147,6 +148,10 @@ extern int mmap_min_addr_handler(struct ctl_table *table, int write,
147 void __user *buffer, size_t *lenp, loff_t *ppos); 148 void __user *buffer, size_t *lenp, loff_t *ppos);
148#endif 149#endif
149 150
151/* security_inode_init_security callback function to write xattrs */
152typedef int (*initxattrs) (struct inode *inode,
153 const struct xattr *xattr_array, void *fs_data);
154
150#ifdef CONFIG_SECURITY 155#ifdef CONFIG_SECURITY
151 156
152struct security_mnt_opts { 157struct security_mnt_opts {
@@ -1704,8 +1709,11 @@ int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
1704int security_inode_alloc(struct inode *inode); 1709int security_inode_alloc(struct inode *inode);
1705void security_inode_free(struct inode *inode); 1710void security_inode_free(struct inode *inode);
1706int security_inode_init_security(struct inode *inode, struct inode *dir, 1711int security_inode_init_security(struct inode *inode, struct inode *dir,
1707 const struct qstr *qstr, char **name, 1712 const struct qstr *qstr,
1708 void **value, size_t *len); 1713 initxattrs initxattrs, void *fs_data);
1714int security_old_inode_init_security(struct inode *inode, struct inode *dir,
1715 const struct qstr *qstr, char **name,
1716 void **value, size_t *len);
1709int security_inode_create(struct inode *dir, struct dentry *dentry, int mode); 1717int security_inode_create(struct inode *dir, struct dentry *dentry, int mode);
1710int security_inode_link(struct dentry *old_dentry, struct inode *dir, 1718int security_inode_link(struct dentry *old_dentry, struct inode *dir,
1711 struct dentry *new_dentry); 1719 struct dentry *new_dentry);
@@ -2034,9 +2042,8 @@ static inline void security_inode_free(struct inode *inode)
2034static inline int security_inode_init_security(struct inode *inode, 2042static inline int security_inode_init_security(struct inode *inode,
2035 struct inode *dir, 2043 struct inode *dir,
2036 const struct qstr *qstr, 2044 const struct qstr *qstr,
2037 char **name, 2045 initxattrs initxattrs,
2038 void **value, 2046 void *fs_data)
2039 size_t *len)
2040{ 2047{
2041 return -EOPNOTSUPP; 2048 return -EOPNOTSUPP;
2042} 2049}
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index aed54c50aa66..b20cb965c322 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -30,6 +30,9 @@
30#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1) 30#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)
31 31
32/* Security namespace */ 32/* Security namespace */
33#define XATTR_EVM_SUFFIX "evm"
34#define XATTR_NAME_EVM XATTR_SECURITY_PREFIX XATTR_EVM_SUFFIX
35
33#define XATTR_SELINUX_SUFFIX "selinux" 36#define XATTR_SELINUX_SUFFIX "selinux"
34#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX 37#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
35 38
@@ -67,6 +70,12 @@ struct xattr_handler {
67 size_t size, int flags, int handler_flags); 70 size_t size, int flags, int handler_flags);
68}; 71};
69 72
73struct xattr {
74 char *name;
75 void *value;
76 size_t value_len;
77};
78
70ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t); 79ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
71ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t); 80ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
72ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); 81ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
@@ -78,7 +87,10 @@ ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer,
78ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size); 87ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
79int generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); 88int generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags);
80int generic_removexattr(struct dentry *dentry, const char *name); 89int generic_removexattr(struct dentry *dentry, const char *name);
81 90ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name,
91 char **xattr_value, size_t size, gfp_t flags);
92int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
93 const char *value, size_t size, gfp_t flags);
82#endif /* __KERNEL__ */ 94#endif /* __KERNEL__ */
83 95
84#endif /* _LINUX_XATTR_H */ 96#endif /* _LINUX_XATTR_H */
diff --git a/mm/shmem.c b/mm/shmem.c
index 32f6763f16fb..2d3577295298 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1458,7 +1458,7 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1458 inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE); 1458 inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
1459 if (inode) { 1459 if (inode) {
1460 error = security_inode_init_security(inode, dir, 1460 error = security_inode_init_security(inode, dir,
1461 &dentry->d_name, NULL, 1461 &dentry->d_name,
1462 NULL, NULL); 1462 NULL, NULL);
1463 if (error) { 1463 if (error) {
1464 if (error != -EOPNOTSUPP) { 1464 if (error != -EOPNOTSUPP) {
@@ -1598,7 +1598,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
1598 if (!inode) 1598 if (!inode)
1599 return -ENOSPC; 1599 return -ENOSPC;
1600 1600
1601 error = security_inode_init_security(inode, dir, &dentry->d_name, NULL, 1601 error = security_inode_init_security(inode, dir, &dentry->d_name,
1602 NULL, NULL); 1602 NULL, NULL);
1603 if (error) { 1603 if (error) {
1604 if (error != -EOPNOTSUPP) { 1604 if (error != -EOPNOTSUPP) {
diff --git a/security/Kconfig b/security/Kconfig
index e0f08b52e4ab..22847a889081 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -186,7 +186,7 @@ source security/smack/Kconfig
186source security/tomoyo/Kconfig 186source security/tomoyo/Kconfig
187source security/apparmor/Kconfig 187source security/apparmor/Kconfig
188 188
189source security/integrity/ima/Kconfig 189source security/integrity/Kconfig
190 190
191choice 191choice
192 prompt "Default security module" 192 prompt "Default security module"
diff --git a/security/Makefile b/security/Makefile
index 8bb0fe9e1ca9..a5e502f8a05b 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -24,5 +24,5 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o
24obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o 24obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
25 25
26# Object integrity file lists 26# Object integrity file lists
27subdir-$(CONFIG_IMA) += integrity/ima 27subdir-$(CONFIG_INTEGRITY) += integrity
28obj-$(CONFIG_IMA) += integrity/ima/built-in.o 28obj-$(CONFIG_INTEGRITY) += integrity/built-in.o
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
new file mode 100644
index 000000000000..4bf00acf7937
--- /dev/null
+++ b/security/integrity/Kconfig
@@ -0,0 +1,7 @@
1#
2config INTEGRITY
3 def_bool y
4 depends on IMA || EVM
5
6source security/integrity/ima/Kconfig
7source security/integrity/evm/Kconfig
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
new file mode 100644
index 000000000000..0ae44aea6516
--- /dev/null
+++ b/security/integrity/Makefile
@@ -0,0 +1,12 @@
1#
2# Makefile for caching inode integrity data (iint)
3#
4
5obj-$(CONFIG_INTEGRITY) += integrity.o
6
7integrity-y := iint.o
8
9subdir-$(CONFIG_IMA) += ima
10obj-$(CONFIG_IMA) += ima/built-in.o
11subdir-$(CONFIG_EVM) += evm
12obj-$(CONFIG_EVM) += evm/built-in.o
diff --git a/security/integrity/evm/Kconfig b/security/integrity/evm/Kconfig
new file mode 100644
index 000000000000..73f654099a4b
--- /dev/null
+++ b/security/integrity/evm/Kconfig
@@ -0,0 +1,12 @@
1config EVM
2 boolean "EVM support"
3 depends on SECURITY && KEYS && ENCRYPTED_KEYS
4 select CRYPTO_HMAC
5 select CRYPTO_MD5
6 select CRYPTO_SHA1
7 default n
8 help
9 EVM protects a file's security extended attributes against
10 integrity attacks.
11
12 If you are unsure how to answer this question, answer N.
diff --git a/security/integrity/evm/Makefile b/security/integrity/evm/Makefile
new file mode 100644
index 000000000000..0787d262b9e3
--- /dev/null
+++ b/security/integrity/evm/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for building the Extended Verification Module(EVM)
3#
4obj-$(CONFIG_EVM) += evm.o
5
6evm-y := evm_main.o evm_crypto.o evm_secfs.o
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
new file mode 100644
index 000000000000..d320f5197437
--- /dev/null
+++ b/security/integrity/evm/evm.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright (C) 2005-2010 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 * Kylene Hall <kjhall@us.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 2 of the License.
11 *
12 * File: evm.h
13 *
14 */
15#include <linux/xattr.h>
16#include <linux/security.h>
17#include "../integrity.h"
18
19extern int evm_initialized;
20extern char *evm_hmac;
21
22extern struct crypto_shash *hmac_tfm;
23
24/* List of EVM protected security xattrs */
25extern char *evm_config_xattrnames[];
26
27extern int evm_init_key(void);
28extern int evm_update_evmxattr(struct dentry *dentry,
29 const char *req_xattr_name,
30 const char *req_xattr_value,
31 size_t req_xattr_value_len);
32extern int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
33 const char *req_xattr_value,
34 size_t req_xattr_value_len, char *digest);
35extern int evm_init_hmac(struct inode *inode, const struct xattr *xattr,
36 char *hmac_val);
37extern int evm_init_secfs(void);
38extern void evm_cleanup_secfs(void);
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
new file mode 100644
index 000000000000..5dd5b140242c
--- /dev/null
+++ b/security/integrity/evm/evm_crypto.c
@@ -0,0 +1,216 @@
1/*
2 * Copyright (C) 2005-2010 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 * Kylene Hall <kjhall@us.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 2 of the License.
11 *
12 * File: evm_crypto.c
13 * Using root's kernel master key (kmk), calculate the HMAC
14 */
15
16#include <linux/module.h>
17#include <linux/crypto.h>
18#include <linux/xattr.h>
19#include <keys/encrypted-type.h>
20#include <crypto/hash.h>
21#include "evm.h"
22
23#define EVMKEY "evm-key"
24#define MAX_KEY_SIZE 128
25static unsigned char evmkey[MAX_KEY_SIZE];
26static int evmkey_len = MAX_KEY_SIZE;
27
28struct crypto_shash *hmac_tfm;
29
30static struct shash_desc *init_desc(void)
31{
32 int rc;
33 struct shash_desc *desc;
34
35 if (hmac_tfm == NULL) {
36 hmac_tfm = crypto_alloc_shash(evm_hmac, 0, CRYPTO_ALG_ASYNC);
37 if (IS_ERR(hmac_tfm)) {
38 pr_err("Can not allocate %s (reason: %ld)\n",
39 evm_hmac, PTR_ERR(hmac_tfm));
40 rc = PTR_ERR(hmac_tfm);
41 hmac_tfm = NULL;
42 return ERR_PTR(rc);
43 }
44 }
45
46 desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac_tfm),
47 GFP_KERNEL);
48 if (!desc)
49 return ERR_PTR(-ENOMEM);
50
51 desc->tfm = hmac_tfm;
52 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
53
54 rc = crypto_shash_setkey(hmac_tfm, evmkey, evmkey_len);
55 if (rc)
56 goto out;
57 rc = crypto_shash_init(desc);
58out:
59 if (rc) {
60 kfree(desc);
61 return ERR_PTR(rc);
62 }
63 return desc;
64}
65
66/* Protect against 'cutting & pasting' security.evm xattr, include inode
67 * specific info.
68 *
69 * (Additional directory/file metadata needs to be added for more complete
70 * protection.)
71 */
72static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
73 char *digest)
74{
75 struct h_misc {
76 unsigned long ino;
77 __u32 generation;
78 uid_t uid;
79 gid_t gid;
80 umode_t mode;
81 } hmac_misc;
82
83 memset(&hmac_misc, 0, sizeof hmac_misc);
84 hmac_misc.ino = inode->i_ino;
85 hmac_misc.generation = inode->i_generation;
86 hmac_misc.uid = inode->i_uid;
87 hmac_misc.gid = inode->i_gid;
88 hmac_misc.mode = inode->i_mode;
89 crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof hmac_misc);
90 crypto_shash_final(desc, digest);
91}
92
93/*
94 * Calculate the HMAC value across the set of protected security xattrs.
95 *
96 * Instead of retrieving the requested xattr, for performance, calculate
97 * the hmac using the requested xattr value. Don't alloc/free memory for
98 * each xattr, but attempt to re-use the previously allocated memory.
99 */
100int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
101 const char *req_xattr_value, size_t req_xattr_value_len,
102 char *digest)
103{
104 struct inode *inode = dentry->d_inode;
105 struct shash_desc *desc;
106 char **xattrname;
107 size_t xattr_size = 0;
108 char *xattr_value = NULL;
109 int error;
110 int size;
111
112 if (!inode->i_op || !inode->i_op->getxattr)
113 return -EOPNOTSUPP;
114 desc = init_desc();
115 if (IS_ERR(desc))
116 return PTR_ERR(desc);
117
118 error = -ENODATA;
119 for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
120 if ((req_xattr_name && req_xattr_value)
121 && !strcmp(*xattrname, req_xattr_name)) {
122 error = 0;
123 crypto_shash_update(desc, (const u8 *)req_xattr_value,
124 req_xattr_value_len);
125 continue;
126 }
127 size = vfs_getxattr_alloc(dentry, *xattrname,
128 &xattr_value, xattr_size, GFP_NOFS);
129 if (size == -ENOMEM) {
130 error = -ENOMEM;
131 goto out;
132 }
133 if (size < 0)
134 continue;
135
136 error = 0;
137 xattr_size = size;
138 crypto_shash_update(desc, (const u8 *)xattr_value, xattr_size);
139 }
140 hmac_add_misc(desc, inode, digest);
141
142out:
143 kfree(xattr_value);
144 kfree(desc);
145 return error;
146}
147
148/*
149 * Calculate the hmac and update security.evm xattr
150 *
151 * Expects to be called with i_mutex locked.
152 */
153int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
154 const char *xattr_value, size_t xattr_value_len)
155{
156 struct inode *inode = dentry->d_inode;
157 struct evm_ima_xattr_data xattr_data;
158 int rc = 0;
159
160 rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
161 xattr_value_len, xattr_data.digest);
162 if (rc == 0) {
163 xattr_data.type = EVM_XATTR_HMAC;
164 rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
165 &xattr_data,
166 sizeof(xattr_data), 0);
167 }
168 else if (rc == -ENODATA)
169 rc = inode->i_op->removexattr(dentry, XATTR_NAME_EVM);
170 return rc;
171}
172
173int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
174 char *hmac_val)
175{
176 struct shash_desc *desc;
177
178 desc = init_desc();
179 if (IS_ERR(desc)) {
180 printk(KERN_INFO "init_desc failed\n");
181 return PTR_ERR(desc);
182 }
183
184 crypto_shash_update(desc, lsm_xattr->value, lsm_xattr->value_len);
185 hmac_add_misc(desc, inode, hmac_val);
186 kfree(desc);
187 return 0;
188}
189
190/*
191 * Get the key from the TPM for the SHA1-HMAC
192 */
193int evm_init_key(void)
194{
195 struct key *evm_key;
196 struct encrypted_key_payload *ekp;
197 int rc = 0;
198
199 evm_key = request_key(&key_type_encrypted, EVMKEY, NULL);
200 if (IS_ERR(evm_key))
201 return -ENOENT;
202
203 down_read(&evm_key->sem);
204 ekp = evm_key->payload.data;
205 if (ekp->decrypted_datalen > MAX_KEY_SIZE) {
206 rc = -EINVAL;
207 goto out;
208 }
209 memcpy(evmkey, ekp->decrypted_data, ekp->decrypted_datalen);
210out:
211 /* burn the original key contents */
212 memset(ekp->decrypted_data, 0, ekp->decrypted_datalen);
213 up_read(&evm_key->sem);
214 key_put(evm_key);
215 return rc;
216}
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
new file mode 100644
index 000000000000..8fc5b5d7ceaa
--- /dev/null
+++ b/security/integrity/evm/evm_main.c
@@ -0,0 +1,384 @@
1/*
2 * Copyright (C) 2005-2010 IBM Corporation
3 *
4 * Author:
5 * Mimi Zohar <zohar@us.ibm.com>
6 * Kylene Hall <kjhall@us.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 2 of the License.
11 *
12 * File: evm_main.c
13 * implements evm_inode_setxattr, evm_inode_post_setxattr,
14 * evm_inode_removexattr, and evm_verifyxattr
15 */
16
17#include <linux/module.h>
18#include <linux/crypto.h>
19#include <linux/xattr.h>
20#include <linux/integrity.h>
21#include <linux/evm.h>
22#include <crypto/hash.h>
23#include "evm.h"
24
25int evm_initialized;
26
27char *evm_hmac = "hmac(sha1)";
28
29char *evm_config_xattrnames[] = {
30#ifdef CONFIG_SECURITY_SELINUX
31 XATTR_NAME_SELINUX,
32#endif
33#ifdef CONFIG_SECURITY_SMACK
34 XATTR_NAME_SMACK,
35#endif
36 XATTR_NAME_CAPS,
37 NULL
38};
39
40static int evm_fixmode;
41static int __init evm_set_fixmode(char *str)
42{
43 if (strncmp(str, "fix", 3) == 0)
44 evm_fixmode = 1;
45 return 0;
46}
47__setup("evm=", evm_set_fixmode);
48
49/*
50 * evm_verify_hmac - calculate and compare the HMAC with the EVM xattr
51 *
52 * Compute the HMAC on the dentry's protected set of extended attributes
53 * and compare it against the stored security.evm xattr.
54 *
55 * For performance:
56 * - use the previoulsy retrieved xattr value and length to calculate the
57 * HMAC.)
58 * - cache the verification result in the iint, when available.
59 *
60 * Returns integrity status
61 */
62static enum integrity_status evm_verify_hmac(struct dentry *dentry,
63 const char *xattr_name,
64 char *xattr_value,
65 size_t xattr_value_len,
66 struct integrity_iint_cache *iint)
67{
68 struct evm_ima_xattr_data xattr_data;
69 enum integrity_status evm_status;
70 int rc;
71
72 if (iint && iint->evm_status == INTEGRITY_PASS)
73 return iint->evm_status;
74
75 /* if status is not PASS, try to check again - against -ENOMEM */
76
77 rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
78 xattr_value_len, xattr_data.digest);
79 if (rc < 0)
80 goto err_out;
81
82 xattr_data.type = EVM_XATTR_HMAC;
83 rc = vfs_xattr_cmp(dentry, XATTR_NAME_EVM, (u8 *)&xattr_data,
84 sizeof xattr_data, GFP_NOFS);
85 if (rc < 0)
86 goto err_out;
87 evm_status = INTEGRITY_PASS;
88 goto out;
89
90err_out:
91 switch (rc) {
92 case -ENODATA: /* file not labelled */
93 evm_status = INTEGRITY_NOLABEL;
94 break;
95 default:
96 evm_status = INTEGRITY_FAIL;
97 }
98out:
99 if (iint)
100 iint->evm_status = evm_status;
101 return evm_status;
102}
103
104static int evm_protected_xattr(const char *req_xattr_name)
105{
106 char **xattrname;
107 int namelen;
108 int found = 0;
109
110 namelen = strlen(req_xattr_name);
111 for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
112 if ((strlen(*xattrname) == namelen)
113 && (strncmp(req_xattr_name, *xattrname, namelen) == 0)) {
114 found = 1;
115 break;
116 }
117 if (strncmp(req_xattr_name,
118 *xattrname + XATTR_SECURITY_PREFIX_LEN,
119 strlen(req_xattr_name)) == 0) {
120 found = 1;
121 break;
122 }
123 }
124 return found;
125}
126
127/**
128 * evm_verifyxattr - verify the integrity of the requested xattr
129 * @dentry: object of the verify xattr
130 * @xattr_name: requested xattr
131 * @xattr_value: requested xattr value
132 * @xattr_value_len: requested xattr value length
133 *
134 * Calculate the HMAC for the given dentry and verify it against the stored
135 * security.evm xattr. For performance, use the xattr value and length
136 * previously retrieved to calculate the HMAC.
137 *
138 * Returns the xattr integrity status.
139 *
140 * This function requires the caller to lock the inode's i_mutex before it
141 * is executed.
142 */
143enum integrity_status evm_verifyxattr(struct dentry *dentry,
144 const char *xattr_name,
145 void *xattr_value, size_t xattr_value_len,
146 struct integrity_iint_cache *iint)
147{
148 if (!evm_initialized || !evm_protected_xattr(xattr_name))
149 return INTEGRITY_UNKNOWN;
150
151 if (!iint) {
152 iint = integrity_iint_find(dentry->d_inode);
153 if (!iint)
154 return INTEGRITY_UNKNOWN;
155 }
156 return evm_verify_hmac(dentry, xattr_name, xattr_value,
157 xattr_value_len, iint);
158}
159EXPORT_SYMBOL_GPL(evm_verifyxattr);
160
161/*
162 * evm_protect_xattr - protect the EVM extended attribute
163 *
164 * Prevent security.evm from being modified or removed.
165 */
166static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
167 const void *xattr_value, size_t xattr_value_len)
168{
169 if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) {
170 if (!capable(CAP_SYS_ADMIN))
171 return -EPERM;
172 }
173 return 0;
174}
175
176/*
177 * evm_verify_current_integrity - verify the dentry's metadata integrity
178 * @dentry: pointer to the affected dentry
179 *
180 * Verify and return the dentry's metadata integrity. The exceptions are
181 * before EVM is initialized or in 'fix' mode.
182 */
183static enum integrity_status evm_verify_current_integrity(struct dentry *dentry)
184{
185 struct inode *inode = dentry->d_inode;
186
187 if (!evm_initialized || !S_ISREG(inode->i_mode) || evm_fixmode)
188 return 0;
189 return evm_verify_hmac(dentry, NULL, NULL, 0, NULL);
190}
191
192/**
193 * evm_inode_setxattr - protect the EVM extended attribute
194 * @dentry: pointer to the affected dentry
195 * @xattr_name: pointer to the affected extended attribute name
196 * @xattr_value: pointer to the new extended attribute value
197 * @xattr_value_len: pointer to the new extended attribute value length
198 *
199 * Updating 'security.evm' requires CAP_SYS_ADMIN privileges and that
200 * the current value is valid.
201 */
202int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
203 const void *xattr_value, size_t xattr_value_len)
204{
205
206 enum integrity_status evm_status;
207 int ret;
208
209 ret = evm_protect_xattr(dentry, xattr_name, xattr_value,
210 xattr_value_len);
211 if (ret)
212 return ret;
213 evm_status = evm_verify_current_integrity(dentry);
214 return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
215}
216
217/**
218 * evm_inode_removexattr - protect the EVM extended attribute
219 * @dentry: pointer to the affected dentry
220 * @xattr_name: pointer to the affected extended attribute name
221 *
222 * Removing 'security.evm' requires CAP_SYS_ADMIN privileges and that
223 * the current value is valid.
224 */
225int evm_inode_removexattr(struct dentry *dentry, const char *xattr_name)
226{
227 enum integrity_status evm_status;
228 int ret;
229
230 ret = evm_protect_xattr(dentry, xattr_name, NULL, 0);
231 if (ret)
232 return ret;
233 evm_status = evm_verify_current_integrity(dentry);
234 return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
235}
236
237/**
238 * evm_inode_post_setxattr - update 'security.evm' to reflect the changes
239 * @dentry: pointer to the affected dentry
240 * @xattr_name: pointer to the affected extended attribute name
241 * @xattr_value: pointer to the new extended attribute value
242 * @xattr_value_len: pointer to the new extended attribute value length
243 *
244 * Update the HMAC stored in 'security.evm' to reflect the change.
245 *
246 * No need to take the i_mutex lock here, as this function is called from
247 * __vfs_setxattr_noperm(). The caller of which has taken the inode's
248 * i_mutex lock.
249 */
250void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
251 const void *xattr_value, size_t xattr_value_len)
252{
253 if (!evm_initialized || !evm_protected_xattr(xattr_name))
254 return;
255
256 evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
257 return;
258}
259
260/**
261 * evm_inode_post_removexattr - update 'security.evm' after removing the xattr
262 * @dentry: pointer to the affected dentry
263 * @xattr_name: pointer to the affected extended attribute name
264 *
265 * Update the HMAC stored in 'security.evm' to reflect removal of the xattr.
266 */
267void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
268{
269 struct inode *inode = dentry->d_inode;
270
271 if (!evm_initialized || !evm_protected_xattr(xattr_name))
272 return;
273
274 mutex_lock(&inode->i_mutex);
275 evm_update_evmxattr(dentry, xattr_name, NULL, 0);
276 mutex_unlock(&inode->i_mutex);
277 return;
278}
279
280/**
281 * evm_inode_setattr - prevent updating an invalid EVM extended attribute
282 * @dentry: pointer to the affected dentry
283 */
284int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
285{
286 unsigned int ia_valid = attr->ia_valid;
287 enum integrity_status evm_status;
288
289 if (ia_valid & ~(ATTR_MODE | ATTR_UID | ATTR_GID))
290 return 0;
291 evm_status = evm_verify_current_integrity(dentry);
292 return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
293}
294
295/**
296 * evm_inode_post_setattr - update 'security.evm' after modifying metadata
297 * @dentry: pointer to the affected dentry
298 * @ia_valid: for the UID and GID status
299 *
300 * For now, update the HMAC stored in 'security.evm' to reflect UID/GID
301 * changes.
302 *
303 * This function is called from notify_change(), which expects the caller
304 * to lock the inode's i_mutex.
305 */
306void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
307{
308 if (!evm_initialized)
309 return;
310
311 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
312 evm_update_evmxattr(dentry, NULL, NULL, 0);
313 return;
314}
315
316/*
317 * evm_inode_init_security - initializes security.evm
318 */
319int evm_inode_init_security(struct inode *inode,
320 const struct xattr *lsm_xattr,
321 struct xattr *evm_xattr)
322{
323 struct evm_ima_xattr_data *xattr_data;
324 int rc;
325
326 if (!evm_initialized || !evm_protected_xattr(lsm_xattr->name))
327 return -EOPNOTSUPP;
328
329 xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
330 if (!xattr_data)
331 return -ENOMEM;
332
333 xattr_data->type = EVM_XATTR_HMAC;
334 rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest);
335 if (rc < 0)
336 goto out;
337
338 evm_xattr->value = xattr_data;
339 evm_xattr->value_len = sizeof(*xattr_data);
340 evm_xattr->name = kstrdup(XATTR_EVM_SUFFIX, GFP_NOFS);
341 return 0;
342out:
343 kfree(xattr_data);
344 return rc;
345}
346EXPORT_SYMBOL_GPL(evm_inode_init_security);
347
348static int __init init_evm(void)
349{
350 int error;
351
352 error = evm_init_secfs();
353 if (error < 0) {
354 printk(KERN_INFO "EVM: Error registering secfs\n");
355 goto err;
356 }
357err:
358 return error;
359}
360
361static void __exit cleanup_evm(void)
362{
363 evm_cleanup_secfs();
364 if (hmac_tfm)
365 crypto_free_shash(hmac_tfm);
366}
367
368/*
369 * evm_display_config - list the EVM protected security extended attributes
370 */
371static int __init evm_display_config(void)
372{
373 char **xattrname;
374
375 for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++)
376 printk(KERN_INFO "EVM: %s\n", *xattrname);
377 return 0;
378}
379
380pure_initcall(evm_display_config);
381late_initcall(init_evm);
382
383MODULE_DESCRIPTION("Extended Verification Module");
384MODULE_LICENSE("GPL");
diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
new file mode 100644
index 000000000000..ac7629950578
--- /dev/null
+++ b/security/integrity/evm/evm_secfs.c
@@ -0,0 +1,108 @@
1/*
2 * Copyright (C) 2010 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
10 *
11 * File: evm_secfs.c
12 * - Used to signal when key is on keyring
13 * - Get the key and enable EVM
14 */
15
16#include <linux/uaccess.h>
17#include <linux/module.h>
18#include "evm.h"
19
20static struct dentry *evm_init_tpm;
21
22/**
23 * evm_read_key - read() for <securityfs>/evm
24 *
25 * @filp: file pointer, not actually used
26 * @buf: where to put the result
27 * @count: maximum to send along
28 * @ppos: where to start
29 *
30 * Returns number of bytes read or error code, as appropriate
31 */
32static ssize_t evm_read_key(struct file *filp, char __user *buf,
33 size_t count, loff_t *ppos)
34{
35 char temp[80];
36 ssize_t rc;
37
38 if (*ppos != 0)
39 return 0;
40
41 sprintf(temp, "%d", evm_initialized);
42 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
43
44 return rc;
45}
46
47/**
48 * evm_write_key - write() for <securityfs>/evm
49 * @file: file pointer, not actually used
50 * @buf: where to get the data from
51 * @count: bytes sent
52 * @ppos: where to start
53 *
54 * Used to signal that key is on the kernel key ring.
55 * - get the integrity hmac key from the kernel key ring
56 * - create list of hmac protected extended attributes
57 * Returns number of bytes written or error code, as appropriate
58 */
59static ssize_t evm_write_key(struct file *file, const char __user *buf,
60 size_t count, loff_t *ppos)
61{
62 char temp[80];
63 int i, error;
64
65 if (!capable(CAP_SYS_ADMIN) || evm_initialized)
66 return -EPERM;
67
68 if (count >= sizeof(temp) || count == 0)
69 return -EINVAL;
70
71 if (copy_from_user(temp, buf, count) != 0)
72 return -EFAULT;
73
74 temp[count] = '\0';
75
76 if ((sscanf(temp, "%d", &i) != 1) || (i != 1))
77 return -EINVAL;
78
79 error = evm_init_key();
80 if (!error) {
81 evm_initialized = 1;
82 pr_info("EVM: initialized\n");
83 } else
84 pr_err("EVM: initialization failed\n");
85 return count;
86}
87
88static const struct file_operations evm_key_ops = {
89 .read = evm_read_key,
90 .write = evm_write_key,
91};
92
93int __init evm_init_secfs(void)
94{
95 int error = 0;
96
97 evm_init_tpm = securityfs_create_file("evm", S_IRUSR | S_IRGRP,
98 NULL, NULL, &evm_key_ops);
99 if (!evm_init_tpm || IS_ERR(evm_init_tpm))
100 error = -EFAULT;
101 return error;
102}
103
104void __exit evm_cleanup_secfs(void)
105{
106 if (evm_init_tpm)
107 securityfs_remove(evm_init_tpm);
108}
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
new file mode 100644
index 000000000000..0a23e075e1d2
--- /dev/null
+++ b/security/integrity/iint.c
@@ -0,0 +1,171 @@
1/*
2 * Copyright (C) 2008 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 *
12 * File: integrity_iint.c
13 * - implements the integrity hooks: integrity_inode_alloc,
14 * integrity_inode_free
15 * - cache integrity information associated with an inode
16 * using a rbtree tree.
17 */
18#include <linux/slab.h>
19#include <linux/module.h>
20#include <linux/spinlock.h>
21#include <linux/rbtree.h>
22#include "integrity.h"
23
24static struct rb_root integrity_iint_tree = RB_ROOT;
25static DEFINE_SPINLOCK(integrity_iint_lock);
26static struct kmem_cache *iint_cache __read_mostly;
27
28int iint_initialized;
29
30/*
31 * __integrity_iint_find - return the iint associated with an inode
32 */
33static struct integrity_iint_cache *__integrity_iint_find(struct inode *inode)
34{
35 struct integrity_iint_cache *iint;
36 struct rb_node *n = integrity_iint_tree.rb_node;
37
38 assert_spin_locked(&integrity_iint_lock);
39
40 while (n) {
41 iint = rb_entry(n, struct integrity_iint_cache, rb_node);
42
43 if (inode < iint->inode)
44 n = n->rb_left;
45 else if (inode > iint->inode)
46 n = n->rb_right;
47 else
48 break;
49 }
50 if (!n)
51 return NULL;
52
53 return iint;
54}
55
56/*
57 * integrity_iint_find - return the iint associated with an inode
58 */
59struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
60{
61 struct integrity_iint_cache *iint;
62
63 if (!IS_IMA(inode))
64 return NULL;
65
66 spin_lock(&integrity_iint_lock);
67 iint = __integrity_iint_find(inode);
68 spin_unlock(&integrity_iint_lock);
69
70 return iint;
71}
72
73static void iint_free(struct integrity_iint_cache *iint)
74{
75 iint->version = 0;
76 iint->flags = 0UL;
77 kmem_cache_free(iint_cache, iint);
78}
79
80/**
81 * integrity_inode_alloc - allocate an iint associated with an inode
82 * @inode: pointer to the inode
83 */
84int integrity_inode_alloc(struct inode *inode)
85{
86 struct rb_node **p;
87 struct rb_node *new_node, *parent = NULL;
88 struct integrity_iint_cache *new_iint, *test_iint;
89 int rc;
90
91 new_iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
92 if (!new_iint)
93 return -ENOMEM;
94
95 new_iint->inode = inode;
96 new_node = &new_iint->rb_node;
97
98 mutex_lock(&inode->i_mutex); /* i_flags */
99 spin_lock(&integrity_iint_lock);
100
101 p = &integrity_iint_tree.rb_node;
102 while (*p) {
103 parent = *p;
104 test_iint = rb_entry(parent, struct integrity_iint_cache,
105 rb_node);
106 rc = -EEXIST;
107 if (inode < test_iint->inode)
108 p = &(*p)->rb_left;
109 else if (inode > test_iint->inode)
110 p = &(*p)->rb_right;
111 else
112 goto out_err;
113 }
114
115 inode->i_flags |= S_IMA;
116 rb_link_node(new_node, parent, p);
117 rb_insert_color(new_node, &integrity_iint_tree);
118
119 spin_unlock(&integrity_iint_lock);
120 mutex_unlock(&inode->i_mutex); /* i_flags */
121
122 return 0;
123out_err:
124 spin_unlock(&integrity_iint_lock);
125 mutex_unlock(&inode->i_mutex); /* i_flags */
126 iint_free(new_iint);
127
128 return rc;
129}
130
131/**
132 * integrity_inode_free - called on security_inode_free
133 * @inode: pointer to the inode
134 *
135 * Free the integrity information(iint) associated with an inode.
136 */
137void integrity_inode_free(struct inode *inode)
138{
139 struct integrity_iint_cache *iint;
140
141 if (!IS_IMA(inode))
142 return;
143
144 spin_lock(&integrity_iint_lock);
145 iint = __integrity_iint_find(inode);
146 rb_erase(&iint->rb_node, &integrity_iint_tree);
147 spin_unlock(&integrity_iint_lock);
148
149 iint_free(iint);
150}
151
152static void init_once(void *foo)
153{
154 struct integrity_iint_cache *iint = foo;
155
156 memset(iint, 0, sizeof *iint);
157 iint->version = 0;
158 iint->flags = 0UL;
159 mutex_init(&iint->mutex);
160 iint->evm_status = INTEGRITY_UNKNOWN;
161}
162
163static int __init integrity_iintcache_init(void)
164{
165 iint_cache =
166 kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache),
167 0, SLAB_PANIC, init_once);
168 iint_initialized = 1;
169 return 0;
170}
171security_initcall(integrity_iintcache_init);
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index b6ecfd4d8d78..19c053b82303 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -3,6 +3,7 @@
3config IMA 3config IMA
4 bool "Integrity Measurement Architecture(IMA)" 4 bool "Integrity Measurement Architecture(IMA)"
5 depends on SECURITY 5 depends on SECURITY
6 select INTEGRITY
6 select SECURITYFS 7 select SECURITYFS
7 select CRYPTO 8 select CRYPTO
8 select CRYPTO_HMAC 9 select CRYPTO_HMAC
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 787c4cb916cd..5690c021de8f 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -6,4 +6,4 @@
6obj-$(CONFIG_IMA) += ima.o 6obj-$(CONFIG_IMA) += ima.o
7 7
8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ 8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
9 ima_policy.o ima_iint.o ima_audit.o 9 ima_policy.o ima_audit.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 08408bd71462..29d97af5e9a4 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -24,11 +24,13 @@
24#include <linux/tpm.h> 24#include <linux/tpm.h>
25#include <linux/audit.h> 25#include <linux/audit.h>
26 26
27#include "../integrity.h"
28
27enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII }; 29enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII };
28enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; 30enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
29 31
30/* digest size for IMA, fits SHA1 or MD5 */ 32/* digest size for IMA, fits SHA1 or MD5 */
31#define IMA_DIGEST_SIZE 20 33#define IMA_DIGEST_SIZE SHA1_DIGEST_SIZE
32#define IMA_EVENT_NAME_LEN_MAX 255 34#define IMA_EVENT_NAME_LEN_MAX 255
33 35
34#define IMA_HASH_BITS 9 36#define IMA_HASH_BITS 9
@@ -96,34 +98,21 @@ static inline unsigned long ima_hash_key(u8 *digest)
96 return hash_long(*digest, IMA_HASH_BITS); 98 return hash_long(*digest, IMA_HASH_BITS);
97} 99}
98 100
99/* iint cache flags */
100#define IMA_MEASURED 0x01
101
102/* integrity data associated with an inode */
103struct ima_iint_cache {
104 struct rb_node rb_node; /* rooted in ima_iint_tree */
105 struct inode *inode; /* back pointer to inode in question */
106 u64 version; /* track inode changes */
107 unsigned char flags;
108 u8 digest[IMA_DIGEST_SIZE];
109 struct mutex mutex; /* protects: version, flags, digest */
110};
111
112/* LIM API function definitions */ 101/* LIM API function definitions */
113int ima_must_measure(struct inode *inode, int mask, int function); 102int ima_must_measure(struct inode *inode, int mask, int function);
114int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file); 103int ima_collect_measurement(struct integrity_iint_cache *iint,
115void ima_store_measurement(struct ima_iint_cache *iint, struct file *file, 104 struct file *file);
105void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
116 const unsigned char *filename); 106 const unsigned char *filename);
117int ima_store_template(struct ima_template_entry *entry, int violation, 107int ima_store_template(struct ima_template_entry *entry, int violation,
118 struct inode *inode); 108 struct inode *inode);
119void ima_template_show(struct seq_file *m, void *e, 109void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show);
120 enum ima_show_type show);
121 110
122/* rbtree tree calls to lookup, insert, delete 111/* rbtree tree calls to lookup, insert, delete
123 * integrity data associated with an inode. 112 * integrity data associated with an inode.
124 */ 113 */
125struct ima_iint_cache *ima_iint_insert(struct inode *inode); 114struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
126struct ima_iint_cache *ima_iint_find(struct inode *inode); 115struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
127 116
128/* IMA policy related functions */ 117/* IMA policy related functions */
129enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK }; 118enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK };
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index da36d2c085a4..0d50df04ccc4 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -126,7 +126,8 @@ int ima_must_measure(struct inode *inode, int mask, int function)
126 * 126 *
127 * Return 0 on success, error code otherwise 127 * Return 0 on success, error code otherwise
128 */ 128 */
129int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file) 129int ima_collect_measurement(struct integrity_iint_cache *iint,
130 struct file *file)
130{ 131{
131 int result = -EEXIST; 132 int result = -EEXIST;
132 133
@@ -156,8 +157,8 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file)
156 * 157 *
157 * Must be called with iint->mutex held. 158 * Must be called with iint->mutex held.
158 */ 159 */
159void ima_store_measurement(struct ima_iint_cache *iint, struct file *file, 160void ima_store_measurement(struct integrity_iint_cache *iint,
160 const unsigned char *filename) 161 struct file *file, const unsigned char *filename)
161{ 162{
162 const char *op = "add_template_measure"; 163 const char *op = "add_template_measure";
163 const char *audit_cause = "ENOMEM"; 164 const char *audit_cause = "ENOMEM";
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
deleted file mode 100644
index 4ae73040ab7b..000000000000
--- a/security/integrity/ima/ima_iint.c
+++ /dev/null
@@ -1,169 +0,0 @@
1/*
2 * Copyright (C) 2008 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 *
12 * File: ima_iint.c
13 * - implements the IMA hooks: ima_inode_alloc, ima_inode_free
14 * - cache integrity information associated with an inode
15 * using a rbtree tree.
16 */
17#include <linux/slab.h>
18#include <linux/module.h>
19#include <linux/spinlock.h>
20#include <linux/rbtree.h>
21#include "ima.h"
22
23static struct rb_root ima_iint_tree = RB_ROOT;
24static DEFINE_SPINLOCK(ima_iint_lock);
25static struct kmem_cache *iint_cache __read_mostly;
26
27int iint_initialized = 0;
28
29/*
30 * __ima_iint_find - return the iint associated with an inode
31 */
32static struct ima_iint_cache *__ima_iint_find(struct inode *inode)
33{
34 struct ima_iint_cache *iint;
35 struct rb_node *n = ima_iint_tree.rb_node;
36
37 assert_spin_locked(&ima_iint_lock);
38
39 while (n) {
40 iint = rb_entry(n, struct ima_iint_cache, rb_node);
41
42 if (inode < iint->inode)
43 n = n->rb_left;
44 else if (inode > iint->inode)
45 n = n->rb_right;
46 else
47 break;
48 }
49 if (!n)
50 return NULL;
51
52 return iint;
53}
54
55/*
56 * ima_iint_find - return the iint associated with an inode
57 */
58struct ima_iint_cache *ima_iint_find(struct inode *inode)
59{
60 struct ima_iint_cache *iint;
61
62 if (!IS_IMA(inode))
63 return NULL;
64
65 spin_lock(&ima_iint_lock);
66 iint = __ima_iint_find(inode);
67 spin_unlock(&ima_iint_lock);
68
69 return iint;
70}
71
72static void iint_free(struct ima_iint_cache *iint)
73{
74 iint->version = 0;
75 iint->flags = 0UL;
76 kmem_cache_free(iint_cache, iint);
77}
78
79/**
80 * ima_inode_alloc - allocate an iint associated with an inode
81 * @inode: pointer to the inode
82 */
83int ima_inode_alloc(struct inode *inode)
84{
85 struct rb_node **p;
86 struct rb_node *new_node, *parent = NULL;
87 struct ima_iint_cache *new_iint, *test_iint;
88 int rc;
89
90 new_iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
91 if (!new_iint)
92 return -ENOMEM;
93
94 new_iint->inode = inode;
95 new_node = &new_iint->rb_node;
96
97 mutex_lock(&inode->i_mutex); /* i_flags */
98 spin_lock(&ima_iint_lock);
99
100 p = &ima_iint_tree.rb_node;
101 while (*p) {
102 parent = *p;
103 test_iint = rb_entry(parent, struct ima_iint_cache, rb_node);
104
105 rc = -EEXIST;
106 if (inode < test_iint->inode)
107 p = &(*p)->rb_left;
108 else if (inode > test_iint->inode)
109 p = &(*p)->rb_right;
110 else
111 goto out_err;
112 }
113
114 inode->i_flags |= S_IMA;
115 rb_link_node(new_node, parent, p);
116 rb_insert_color(new_node, &ima_iint_tree);
117
118 spin_unlock(&ima_iint_lock);
119 mutex_unlock(&inode->i_mutex); /* i_flags */
120
121 return 0;
122out_err:
123 spin_unlock(&ima_iint_lock);
124 mutex_unlock(&inode->i_mutex); /* i_flags */
125 iint_free(new_iint);
126
127 return rc;
128}
129
130/**
131 * ima_inode_free - called on security_inode_free
132 * @inode: pointer to the inode
133 *
134 * Free the integrity information(iint) associated with an inode.
135 */
136void ima_inode_free(struct inode *inode)
137{
138 struct ima_iint_cache *iint;
139
140 if (!IS_IMA(inode))
141 return;
142
143 spin_lock(&ima_iint_lock);
144 iint = __ima_iint_find(inode);
145 rb_erase(&iint->rb_node, &ima_iint_tree);
146 spin_unlock(&ima_iint_lock);
147
148 iint_free(iint);
149}
150
151static void init_once(void *foo)
152{
153 struct ima_iint_cache *iint = foo;
154
155 memset(iint, 0, sizeof *iint);
156 iint->version = 0;
157 iint->flags = 0UL;
158 mutex_init(&iint->mutex);
159}
160
161static int __init ima_iintcache_init(void)
162{
163 iint_cache =
164 kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0,
165 SLAB_PANIC, init_once);
166 iint_initialized = 1;
167 return 0;
168}
169security_initcall(ima_iintcache_init);
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 26b46ff74663..42dc27007fdd 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -82,7 +82,7 @@ out:
82 "open_writers"); 82 "open_writers");
83} 83}
84 84
85static void ima_check_last_writer(struct ima_iint_cache *iint, 85static void ima_check_last_writer(struct integrity_iint_cache *iint,
86 struct inode *inode, 86 struct inode *inode,
87 struct file *file) 87 struct file *file)
88{ 88{
@@ -105,12 +105,12 @@ static void ima_check_last_writer(struct ima_iint_cache *iint,
105void ima_file_free(struct file *file) 105void ima_file_free(struct file *file)
106{ 106{
107 struct inode *inode = file->f_dentry->d_inode; 107 struct inode *inode = file->f_dentry->d_inode;
108 struct ima_iint_cache *iint; 108 struct integrity_iint_cache *iint;
109 109
110 if (!iint_initialized || !S_ISREG(inode->i_mode)) 110 if (!iint_initialized || !S_ISREG(inode->i_mode))
111 return; 111 return;
112 112
113 iint = ima_iint_find(inode); 113 iint = integrity_iint_find(inode);
114 if (!iint) 114 if (!iint)
115 return; 115 return;
116 116
@@ -121,7 +121,7 @@ static int process_measurement(struct file *file, const unsigned char *filename,
121 int mask, int function) 121 int mask, int function)
122{ 122{
123 struct inode *inode = file->f_dentry->d_inode; 123 struct inode *inode = file->f_dentry->d_inode;
124 struct ima_iint_cache *iint; 124 struct integrity_iint_cache *iint;
125 int rc = 0; 125 int rc = 0;
126 126
127 if (!ima_initialized || !S_ISREG(inode->i_mode)) 127 if (!ima_initialized || !S_ISREG(inode->i_mode))
@@ -131,9 +131,9 @@ static int process_measurement(struct file *file, const unsigned char *filename,
131 if (rc != 0) 131 if (rc != 0)
132 return rc; 132 return rc;
133retry: 133retry:
134 iint = ima_iint_find(inode); 134 iint = integrity_iint_find(inode);
135 if (!iint) { 135 if (!iint) {
136 rc = ima_inode_alloc(inode); 136 rc = integrity_inode_alloc(inode);
137 if (!rc || rc == -EEXIST) 137 if (!rc || rc == -EEXIST)
138 goto retry; 138 goto retry;
139 return rc; 139 return rc;
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
new file mode 100644
index 000000000000..880bbee2f534
--- /dev/null
+++ b/security/integrity/integrity.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (C) 2009-2010 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 *
12 */
13
14#include <linux/types.h>
15#include <linux/integrity.h>
16#include <crypto/sha.h>
17
18/* iint cache flags */
19#define IMA_MEASURED 0x01
20
21enum evm_ima_xattr_type {
22 IMA_XATTR_DIGEST = 0x01,
23 EVM_XATTR_HMAC,
24 EVM_IMA_XATTR_DIGSIG,
25};
26
27struct evm_ima_xattr_data {
28 u8 type;
29 u8 digest[SHA1_DIGEST_SIZE];
30} __attribute__((packed));
31
32/* integrity data associated with an inode */
33struct integrity_iint_cache {
34 struct rb_node rb_node; /* rooted in integrity_iint_tree */
35 struct inode *inode; /* back pointer to inode in question */
36 u64 version; /* track inode changes */
37 unsigned char flags;
38 u8 digest[SHA1_DIGEST_SIZE];
39 struct mutex mutex; /* protects: version, flags, digest */
40 enum integrity_status evm_status;
41};
42
43/* rbtree tree calls to lookup, insert, delete
44 * integrity data associated with an inode.
45 */
46struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
47struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
diff --git a/security/security.c b/security/security.c
index 0e4fccfef12c..a6328421a055 100644
--- a/security/security.c
+++ b/security/security.c
@@ -16,7 +16,11 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/security.h> 18#include <linux/security.h>
19#include <linux/integrity.h>
19#include <linux/ima.h> 20#include <linux/ima.h>
21#include <linux/evm.h>
22
23#define MAX_LSM_EVM_XATTR 2
20 24
21/* Boot-time LSM user choice */ 25/* Boot-time LSM user choice */
22static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = 26static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
@@ -334,20 +338,57 @@ int security_inode_alloc(struct inode *inode)
334 338
335void security_inode_free(struct inode *inode) 339void security_inode_free(struct inode *inode)
336{ 340{
337 ima_inode_free(inode); 341 integrity_inode_free(inode);
338 security_ops->inode_free_security(inode); 342 security_ops->inode_free_security(inode);
339} 343}
340 344
341int security_inode_init_security(struct inode *inode, struct inode *dir, 345int security_inode_init_security(struct inode *inode, struct inode *dir,
342 const struct qstr *qstr, char **name, 346 const struct qstr *qstr,
343 void **value, size_t *len) 347 const initxattrs initxattrs, void *fs_data)
348{
349 struct xattr new_xattrs[MAX_LSM_EVM_XATTR + 1];
350 struct xattr *lsm_xattr, *evm_xattr, *xattr;
351 int ret;
352
353 if (unlikely(IS_PRIVATE(inode)))
354 return -EOPNOTSUPP;
355
356 memset(new_xattrs, 0, sizeof new_xattrs);
357 if (!initxattrs)
358 return security_ops->inode_init_security(inode, dir, qstr,
359 NULL, NULL, NULL);
360 lsm_xattr = new_xattrs;
361 ret = security_ops->inode_init_security(inode, dir, qstr,
362 &lsm_xattr->name,
363 &lsm_xattr->value,
364 &lsm_xattr->value_len);
365 if (ret)
366 goto out;
367
368 evm_xattr = lsm_xattr + 1;
369 ret = evm_inode_init_security(inode, lsm_xattr, evm_xattr);
370 if (ret)
371 goto out;
372 ret = initxattrs(inode, new_xattrs, fs_data);
373out:
374 for (xattr = new_xattrs; xattr->name != NULL; xattr++) {
375 kfree(xattr->name);
376 kfree(xattr->value);
377 }
378 return (ret == -EOPNOTSUPP) ? 0 : ret;
379}
380EXPORT_SYMBOL(security_inode_init_security);
381
382int security_old_inode_init_security(struct inode *inode, struct inode *dir,
383 const struct qstr *qstr, char **name,
384 void **value, size_t *len)
344{ 385{
345 if (unlikely(IS_PRIVATE(inode))) 386 if (unlikely(IS_PRIVATE(inode)))
346 return -EOPNOTSUPP; 387 return -EOPNOTSUPP;
347 return security_ops->inode_init_security(inode, dir, qstr, name, value, 388 return security_ops->inode_init_security(inode, dir, qstr, name, value,
348 len); 389 len);
349} 390}
350EXPORT_SYMBOL(security_inode_init_security); 391EXPORT_SYMBOL(security_old_inode_init_security);
351 392
352#ifdef CONFIG_SECURITY_PATH 393#ifdef CONFIG_SECURITY_PATH
353int security_path_mknod(struct path *dir, struct dentry *dentry, int mode, 394int security_path_mknod(struct path *dir, struct dentry *dentry, int mode,
@@ -523,9 +564,14 @@ int security_inode_permission(struct inode *inode, int mask)
523 564
524int security_inode_setattr(struct dentry *dentry, struct iattr *attr) 565int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
525{ 566{
567 int ret;
568
526 if (unlikely(IS_PRIVATE(dentry->d_inode))) 569 if (unlikely(IS_PRIVATE(dentry->d_inode)))
527 return 0; 570 return 0;
528 return security_ops->inode_setattr(dentry, attr); 571 ret = security_ops->inode_setattr(dentry, attr);
572 if (ret)
573 return ret;
574 return evm_inode_setattr(dentry, attr);
529} 575}
530EXPORT_SYMBOL_GPL(security_inode_setattr); 576EXPORT_SYMBOL_GPL(security_inode_setattr);
531 577
@@ -539,9 +585,14 @@ int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
539int security_inode_setxattr(struct dentry *dentry, const char *name, 585int security_inode_setxattr(struct dentry *dentry, const char *name,
540 const void *value, size_t size, int flags) 586 const void *value, size_t size, int flags)
541{ 587{
588 int ret;
589
542 if (unlikely(IS_PRIVATE(dentry->d_inode))) 590 if (unlikely(IS_PRIVATE(dentry->d_inode)))
543 return 0; 591 return 0;
544 return security_ops->inode_setxattr(dentry, name, value, size, flags); 592 ret = security_ops->inode_setxattr(dentry, name, value, size, flags);
593 if (ret)
594 return ret;
595 return evm_inode_setxattr(dentry, name, value, size);
545} 596}
546 597
547void security_inode_post_setxattr(struct dentry *dentry, const char *name, 598void security_inode_post_setxattr(struct dentry *dentry, const char *name,
@@ -550,6 +601,7 @@ void security_inode_post_setxattr(struct dentry *dentry, const char *name,
550 if (unlikely(IS_PRIVATE(dentry->d_inode))) 601 if (unlikely(IS_PRIVATE(dentry->d_inode)))
551 return; 602 return;
552 security_ops->inode_post_setxattr(dentry, name, value, size, flags); 603 security_ops->inode_post_setxattr(dentry, name, value, size, flags);
604 evm_inode_post_setxattr(dentry, name, value, size);
553} 605}
554 606
555int security_inode_getxattr(struct dentry *dentry, const char *name) 607int security_inode_getxattr(struct dentry *dentry, const char *name)
@@ -568,9 +620,14 @@ int security_inode_listxattr(struct dentry *dentry)
568 620
569int security_inode_removexattr(struct dentry *dentry, const char *name) 621int security_inode_removexattr(struct dentry *dentry, const char *name)
570{ 622{
623 int ret;
624
571 if (unlikely(IS_PRIVATE(dentry->d_inode))) 625 if (unlikely(IS_PRIVATE(dentry->d_inode)))
572 return 0; 626 return 0;
573 return security_ops->inode_removexattr(dentry, name); 627 ret = security_ops->inode_removexattr(dentry, name);
628 if (ret)
629 return ret;
630 return evm_inode_removexattr(dentry, name);
574} 631}
575 632
576int security_inode_need_killpriv(struct dentry *dentry) 633int security_inode_need_killpriv(struct dentry *dentry)