Explorar o código

Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity into next

James Morris %!s(int64=11) %!d(string=hai) anos
pai
achega
ac60ab4b49

+ 1 - 1
fs/namei.c

@@ -3058,7 +3058,7 @@ opened:
 	error = open_check_o_direct(file);
 	error = open_check_o_direct(file);
 	if (error)
 	if (error)
 		goto exit_fput;
 		goto exit_fput;
-	error = ima_file_check(file, op->acc_mode);
+	error = ima_file_check(file, op->acc_mode, *opened);
 	if (error)
 	if (error)
 		goto exit_fput;
 		goto exit_fput;
 
 

+ 1 - 1
fs/nfsd/vfs.c

@@ -709,7 +709,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
 		host_err = PTR_ERR(*filp);
 		host_err = PTR_ERR(*filp);
 		*filp = NULL;
 		*filp = NULL;
 	} else {
 	} else {
-		host_err = ima_file_check(*filp, may_flags);
+		host_err = ima_file_check(*filp, may_flags, 0);
 
 
 		if (may_flags & NFSD_MAY_64BIT_COOKIE)
 		if (may_flags & NFSD_MAY_64BIT_COOKIE)
 			(*filp)->f_mode |= FMODE_64BITHASH;
 			(*filp)->f_mode |= FMODE_64BITHASH;

+ 2 - 2
include/linux/ima.h

@@ -15,7 +15,7 @@ struct linux_binprm;
 
 
 #ifdef CONFIG_IMA
 #ifdef CONFIG_IMA
 extern int ima_bprm_check(struct linux_binprm *bprm);
 extern int ima_bprm_check(struct linux_binprm *bprm);
-extern int ima_file_check(struct file *file, int mask);
+extern int ima_file_check(struct file *file, int mask, int opened);
 extern void ima_file_free(struct file *file);
 extern void ima_file_free(struct file *file);
 extern int ima_file_mmap(struct file *file, unsigned long prot);
 extern int ima_file_mmap(struct file *file, unsigned long prot);
 extern int ima_module_check(struct file *file);
 extern int ima_module_check(struct file *file);
@@ -27,7 +27,7 @@ static inline int ima_bprm_check(struct linux_binprm *bprm)
 	return 0;
 	return 0;
 }
 }
 
 
-static inline int ima_file_check(struct file *file, int mask)
+static inline int ima_file_check(struct file *file, int mask, int opened)
 {
 {
 	return 0;
 	return 0;
 }
 }

+ 30 - 16
security/integrity/Kconfig

@@ -1,11 +1,23 @@
 #
 #
 config INTEGRITY
 config INTEGRITY
-	def_bool y
-	depends on IMA || EVM
+	bool "Integrity subsystem"
+	depends on SECURITY
+	default y
+	help
+	  This option enables the integrity subsystem, which is comprised
+	  of a number of different components including the Integrity
+	  Measurement Architecture (IMA), Extended Verification Module
+	  (EVM), IMA-appraisal extension, digital signature verification
+	  extension and audit measurement log support.
+
+	  Each of these components can be enabled/disabled separately.
+	  Refer to the individual components for additional details.
+
+if INTEGRITY
 
 
 config INTEGRITY_SIGNATURE
 config INTEGRITY_SIGNATURE
 	boolean "Digital signature verification using multiple keyrings"
 	boolean "Digital signature verification using multiple keyrings"
-	depends on INTEGRITY && KEYS
+	depends on KEYS
 	default n
 	default n
 	select SIGNATURE
 	select SIGNATURE
 	help
 	help
@@ -17,9 +29,21 @@ config INTEGRITY_SIGNATURE
 	  This is useful for evm and module keyrings, when keys are
 	  This is useful for evm and module keyrings, when keys are
 	  usually only added from initramfs.
 	  usually only added from initramfs.
 
 
+config INTEGRITY_ASYMMETRIC_KEYS
+	boolean "Enable asymmetric keys support"
+	depends on INTEGRITY_SIGNATURE
+	default n
+        select ASYMMETRIC_KEY_TYPE
+        select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+        select PUBLIC_KEY_ALGO_RSA
+        select X509_CERTIFICATE_PARSER
+	help
+	  This option enables digital signature verification using
+	  asymmetric keys.
+
 config INTEGRITY_AUDIT
 config INTEGRITY_AUDIT
 	bool "Enables integrity auditing support "
 	bool "Enables integrity auditing support "
-	depends on INTEGRITY && AUDIT
+	depends on AUDIT
 	default y
 	default y
 	help
 	help
 	  In addition to enabling integrity auditing support, this
 	  In addition to enabling integrity auditing support, this
@@ -32,17 +56,7 @@ config INTEGRITY_AUDIT
 	  be enabled by specifying 'integrity_audit=1' on the kernel
 	  be enabled by specifying 'integrity_audit=1' on the kernel
 	  command line.
 	  command line.
 
 
-config INTEGRITY_ASYMMETRIC_KEYS
-	boolean "Enable asymmetric keys support"
-	depends on INTEGRITY_SIGNATURE
-	default n
-        select ASYMMETRIC_KEY_TYPE
-        select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
-        select PUBLIC_KEY_ALGO_RSA
-        select X509_CERTIFICATE_PARSER
-	help
-	  This option enables digital signature verification using
-	  asymmetric keys.
-
 source security/integrity/ima/Kconfig
 source security/integrity/ima/Kconfig
 source security/integrity/evm/Kconfig
 source security/integrity/evm/Kconfig
+
+endif   # if INTEGRITY

+ 3 - 3
security/integrity/Makefile

@@ -3,11 +3,11 @@
 #
 #
 
 
 obj-$(CONFIG_INTEGRITY) += integrity.o
 obj-$(CONFIG_INTEGRITY) += integrity.o
-obj-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
-obj-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
-obj-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
 
 
 integrity-y := iint.o
 integrity-y := iint.o
+integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
+integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
+integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
 
 
 subdir-$(CONFIG_IMA)			+= ima
 subdir-$(CONFIG_IMA)			+= ima
 obj-$(CONFIG_IMA)			+= ima/
 obj-$(CONFIG_IMA)			+= ima/

+ 3 - 2
security/integrity/digsig_asymmetric.c

@@ -13,6 +13,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 
 #include <linux/err.h>
 #include <linux/err.h>
+#include <linux/ratelimit.h>
 #include <linux/key-type.h>
 #include <linux/key-type.h>
 #include <crypto/public_key.h>
 #include <crypto/public_key.h>
 #include <keys/asymmetric-type.h>
 #include <keys/asymmetric-type.h>
@@ -45,8 +46,8 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
 	}
 	}
 
 
 	if (IS_ERR(key)) {
 	if (IS_ERR(key)) {
-		pr_warn("Request for unknown key '%s' err %ld\n",
-			name, PTR_ERR(key));
+		pr_err_ratelimited("Request for unknown key '%s' err %ld\n",
+				   name, PTR_ERR(key));
 		switch (PTR_ERR(key)) {
 		switch (PTR_ERR(key)) {
 			/* Hide some search errors */
 			/* Hide some search errors */
 		case -EACCES:
 		case -EACCES:

+ 0 - 8
security/integrity/evm/Kconfig

@@ -1,6 +1,5 @@
 config EVM
 config EVM
 	boolean "EVM support"
 	boolean "EVM support"
-	depends on SECURITY
 	select KEYS
 	select KEYS
 	select ENCRYPTED_KEYS
 	select ENCRYPTED_KEYS
 	select CRYPTO_HMAC
 	select CRYPTO_HMAC
@@ -12,10 +11,6 @@ config EVM
 
 
 	  If you are unsure how to answer this question, answer N.
 	  If you are unsure how to answer this question, answer N.
 
 
-if EVM
-
-menu "EVM options"
-
 config EVM_ATTR_FSUUID
 config EVM_ATTR_FSUUID
 	bool "FSUUID (version 2)"
 	bool "FSUUID (version 2)"
 	default y
 	default y
@@ -47,6 +42,3 @@ config EVM_EXTRA_SMACK_XATTRS
 	  additional info to the calculation, requires existing EVM
 	  additional info to the calculation, requires existing EVM
 	  labeled file systems to be relabeled.
 	  labeled file systems to be relabeled.
 
 
-endmenu
-
-endif

+ 11 - 6
security/integrity/evm/evm_main.c

@@ -126,14 +126,15 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 	rc = vfs_getxattr_alloc(dentry, XATTR_NAME_EVM, (char **)&xattr_data, 0,
 	rc = vfs_getxattr_alloc(dentry, XATTR_NAME_EVM, (char **)&xattr_data, 0,
 				GFP_NOFS);
 				GFP_NOFS);
 	if (rc <= 0) {
 	if (rc <= 0) {
-		if (rc == 0)
-			evm_status = INTEGRITY_FAIL; /* empty */
-		else if (rc == -ENODATA) {
+		evm_status = INTEGRITY_FAIL;
+		if (rc == -ENODATA) {
 			rc = evm_find_protected_xattrs(dentry);
 			rc = evm_find_protected_xattrs(dentry);
 			if (rc > 0)
 			if (rc > 0)
 				evm_status = INTEGRITY_NOLABEL;
 				evm_status = INTEGRITY_NOLABEL;
 			else if (rc == 0)
 			else if (rc == 0)
 				evm_status = INTEGRITY_NOXATTRS; /* new file */
 				evm_status = INTEGRITY_NOXATTRS; /* new file */
+		} else if (rc == -EOPNOTSUPP) {
+			evm_status = INTEGRITY_UNKNOWN;
 		}
 		}
 		goto out;
 		goto out;
 	}
 	}
@@ -284,6 +285,13 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
 		goto out;
 		goto out;
 	}
 	}
 	evm_status = evm_verify_current_integrity(dentry);
 	evm_status = evm_verify_current_integrity(dentry);
+	if (evm_status == INTEGRITY_NOXATTRS) {
+		struct integrity_iint_cache *iint;
+
+		iint = integrity_iint_find(dentry->d_inode);
+		if (iint && (iint->flags & IMA_NEW_FILE))
+			return 0;
+	}
 out:
 out:
 	if (evm_status != INTEGRITY_PASS)
 	if (evm_status != INTEGRITY_PASS)
 		integrity_audit_msg(AUDIT_INTEGRITY_METADATA, dentry->d_inode,
 		integrity_audit_msg(AUDIT_INTEGRITY_METADATA, dentry->d_inode,
@@ -352,7 +360,6 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
 		return;
 		return;
 
 
 	evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
 	evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
-	return;
 }
 }
 
 
 /**
 /**
@@ -372,7 +379,6 @@ void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
 	mutex_lock(&inode->i_mutex);
 	mutex_lock(&inode->i_mutex);
 	evm_update_evmxattr(dentry, xattr_name, NULL, 0);
 	evm_update_evmxattr(dentry, xattr_name, NULL, 0);
 	mutex_unlock(&inode->i_mutex);
 	mutex_unlock(&inode->i_mutex);
-	return;
 }
 }
 
 
 /**
 /**
@@ -414,7 +420,6 @@ void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
 
 
 	if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
 	if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
 		evm_update_evmxattr(dentry, NULL, NULL, 0);
 		evm_update_evmxattr(dentry, NULL, NULL, 0);
-	return;
 }
 }
 
 
 /*
 /*

+ 0 - 2
security/integrity/ima/Kconfig

@@ -2,8 +2,6 @@
 #
 #
 config IMA
 config IMA
 	bool "Integrity Measurement Architecture(IMA)"
 	bool "Integrity Measurement Architecture(IMA)"
-	depends on SECURITY
-	select INTEGRITY
 	select SECURITYFS
 	select SECURITYFS
 	select CRYPTO
 	select CRYPTO
 	select CRYPTO_HMAC
 	select CRYPTO_HMAC

+ 2 - 13
security/integrity/ima/ima.h

@@ -90,10 +90,7 @@ extern struct list_head ima_measurements;	/* list of all measurements */
 
 
 /* Internal IMA function definitions */
 /* Internal IMA function definitions */
 int ima_init(void);
 int ima_init(void);
-void ima_cleanup(void);
 int ima_fs_init(void);
 int ima_fs_init(void);
-void ima_fs_cleanup(void);
-int ima_inode_alloc(struct inode *inode);
 int ima_add_template_entry(struct ima_template_entry *entry, int violation,
 int ima_add_template_entry(struct ima_template_entry *entry, int violation,
 			   const char *op, struct inode *inode,
 			   const char *op, struct inode *inode,
 			   const unsigned char *filename);
 			   const unsigned char *filename);
@@ -110,8 +107,6 @@ void ima_print_digest(struct seq_file *m, u8 *digest, int size);
 struct ima_template_desc *ima_template_desc_current(void);
 struct ima_template_desc *ima_template_desc_current(void);
 int ima_init_template(void);
 int ima_init_template(void);
 
 
-int ima_init_template(void);
-
 /*
 /*
  * used to protect h_table and sha_table
  * used to protect h_table and sha_table
  */
  */
@@ -151,12 +146,6 @@ int ima_store_template(struct ima_template_entry *entry, int violation,
 void ima_free_template_entry(struct ima_template_entry *entry);
 void ima_free_template_entry(struct ima_template_entry *entry);
 const char *ima_d_path(struct path *path, char **pathbuf);
 const char *ima_d_path(struct path *path, char **pathbuf);
 
 
-/* rbtree tree calls to lookup, insert, delete
- * integrity data associated with an inode.
- */
-struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
-struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
-
 /* IMA policy related functions */
 /* IMA policy related functions */
 enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, FIRMWARE_CHECK, POST_SETATTR };
 enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, FIRMWARE_CHECK, POST_SETATTR };
 
 
@@ -177,7 +166,7 @@ void ima_delete_rules(void);
 int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
 int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
 			     struct file *file, const unsigned char *filename,
 			     struct file *file, const unsigned char *filename,
 			     struct evm_ima_xattr_data *xattr_value,
 			     struct evm_ima_xattr_data *xattr_value,
-			     int xattr_len);
+			     int xattr_len, int opened);
 int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
 int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
 void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
 void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
 enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
 enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
@@ -193,7 +182,7 @@ static inline int ima_appraise_measurement(int func,
 					   struct file *file,
 					   struct file *file,
 					   const unsigned char *filename,
 					   const unsigned char *filename,
 					   struct evm_ima_xattr_data *xattr_value,
 					   struct evm_ima_xattr_data *xattr_value,
-					   int xattr_len)
+					   int xattr_len, int opened)
 {
 {
 	return INTEGRITY_UNKNOWN;
 	return INTEGRITY_UNKNOWN;
 }
 }

+ 2 - 3
security/integrity/ima/ima_api.c

@@ -330,10 +330,9 @@ const char *ima_d_path(struct path *path, char **pathbuf)
 {
 {
 	char *pathname = NULL;
 	char *pathname = NULL;
 
 
-	/* We will allow 11 spaces for ' (deleted)' to be appended */
-	*pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL);
+	*pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
 	if (*pathbuf) {
 	if (*pathbuf) {
-		pathname = d_path(path, *pathbuf, PATH_MAX + 11);
+		pathname = d_absolute_path(path, *pathbuf, PATH_MAX);
 		if (IS_ERR(pathname)) {
 		if (IS_ERR(pathname)) {
 			kfree(*pathbuf);
 			kfree(*pathbuf);
 			*pathbuf = NULL;
 			*pathbuf = NULL;

+ 6 - 5
security/integrity/ima/ima_appraise.c

@@ -183,7 +183,7 @@ int ima_read_xattr(struct dentry *dentry,
 int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
 int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
 			     struct file *file, const unsigned char *filename,
 			     struct file *file, const unsigned char *filename,
 			     struct evm_ima_xattr_data *xattr_value,
 			     struct evm_ima_xattr_data *xattr_value,
-			     int xattr_len)
+			     int xattr_len, int opened)
 {
 {
 	static const char op[] = "appraise_data";
 	static const char op[] = "appraise_data";
 	char *cause = "unknown";
 	char *cause = "unknown";
@@ -192,8 +192,6 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
 	enum integrity_status status = INTEGRITY_UNKNOWN;
 	enum integrity_status status = INTEGRITY_UNKNOWN;
 	int rc = xattr_len, hash_start = 0;
 	int rc = xattr_len, hash_start = 0;
 
 
-	if (!ima_appraise)
-		return 0;
 	if (!inode->i_op->getxattr)
 	if (!inode->i_op->getxattr)
 		return INTEGRITY_UNKNOWN;
 		return INTEGRITY_UNKNOWN;
 
 
@@ -202,8 +200,11 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
 			goto out;
 			goto out;
 
 
 		cause = "missing-hash";
 		cause = "missing-hash";
-		status =
-		    (inode->i_size == 0) ? INTEGRITY_PASS : INTEGRITY_NOLABEL;
+		status = INTEGRITY_NOLABEL;
+		if (opened & FILE_CREATED) {
+			iint->flags |= IMA_NEW_FILE;
+			status = INTEGRITY_PASS;
+		}
 		goto out;
 		goto out;
 	}
 	}
 
 

+ 13 - 7
security/integrity/ima/ima_crypto.c

@@ -80,24 +80,24 @@ static int ima_kernel_read(struct file *file, loff_t offset,
 {
 {
 	mm_segment_t old_fs;
 	mm_segment_t old_fs;
 	char __user *buf = addr;
 	char __user *buf = addr;
-	ssize_t ret;
+	ssize_t ret = -EINVAL;
 
 
 	if (!(file->f_mode & FMODE_READ))
 	if (!(file->f_mode & FMODE_READ))
 		return -EBADF;
 		return -EBADF;
-	if (!file->f_op->read && !file->f_op->aio_read)
-		return -EINVAL;
 
 
 	old_fs = get_fs();
 	old_fs = get_fs();
 	set_fs(get_ds());
 	set_fs(get_ds());
 	if (file->f_op->read)
 	if (file->f_op->read)
 		ret = file->f_op->read(file, buf, count, &offset);
 		ret = file->f_op->read(file, buf, count, &offset);
-	else
+	else if (file->f_op->aio_read)
 		ret = do_sync_read(file, buf, count, &offset);
 		ret = do_sync_read(file, buf, count, &offset);
+	else if (file->f_op->read_iter)
+		ret = new_sync_read(file, buf, count, &offset);
 	set_fs(old_fs);
 	set_fs(old_fs);
 	return ret;
 	return ret;
 }
 }
 
 
-int ima_init_crypto(void)
+int __init ima_init_crypto(void)
 {
 {
 	long rc;
 	long rc;
 
 
@@ -116,7 +116,10 @@ static struct crypto_shash *ima_alloc_tfm(enum hash_algo algo)
 	struct crypto_shash *tfm = ima_shash_tfm;
 	struct crypto_shash *tfm = ima_shash_tfm;
 	int rc;
 	int rc;
 
 
-	if (algo != ima_hash_algo && algo < HASH_ALGO__LAST) {
+	if (algo < 0 || algo >= HASH_ALGO__LAST)
+		algo = ima_hash_algo;
+
+	if (algo != ima_hash_algo) {
 		tfm = crypto_alloc_shash(hash_algo_name[algo], 0, 0);
 		tfm = crypto_alloc_shash(hash_algo_name[algo], 0, 0);
 		if (IS_ERR(tfm)) {
 		if (IS_ERR(tfm)) {
 			rc = PTR_ERR(tfm);
 			rc = PTR_ERR(tfm);
@@ -200,7 +203,10 @@ static struct crypto_ahash *ima_alloc_atfm(enum hash_algo algo)
 	struct crypto_ahash *tfm = ima_ahash_tfm;
 	struct crypto_ahash *tfm = ima_ahash_tfm;
 	int rc;
 	int rc;
 
 
-	if ((algo != ima_hash_algo && algo < HASH_ALGO__LAST) || !tfm) {
+	if (algo < 0 || algo >= HASH_ALGO__LAST)
+		algo = ima_hash_algo;
+
+	if (algo != ima_hash_algo || !tfm) {
 		tfm = crypto_alloc_ahash(hash_algo_name[algo], 0, 0);
 		tfm = crypto_alloc_ahash(hash_algo_name[algo], 0, 0);
 		if (!IS_ERR(tfm)) {
 		if (!IS_ERR(tfm)) {
 			if (algo == ima_hash_algo)
 			if (algo == ima_hash_algo)

+ 25 - 27
security/integrity/ima/ima_main.c

@@ -124,11 +124,13 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint,
 		return;
 		return;
 
 
 	mutex_lock(&inode->i_mutex);
 	mutex_lock(&inode->i_mutex);
-	if (atomic_read(&inode->i_writecount) == 1 &&
-	    iint->version != inode->i_version) {
-		iint->flags &= ~IMA_DONE_MASK;
-		if (iint->flags & IMA_APPRAISE)
-			ima_update_xattr(iint, file);
+	if (atomic_read(&inode->i_writecount) == 1) {
+		if ((iint->version != inode->i_version) ||
+		    (iint->flags & IMA_NEW_FILE)) {
+			iint->flags &= ~(IMA_DONE_MASK | IMA_NEW_FILE);
+			if (iint->flags & IMA_APPRAISE)
+				ima_update_xattr(iint, file);
+		}
 	}
 	}
 	mutex_unlock(&inode->i_mutex);
 	mutex_unlock(&inode->i_mutex);
 }
 }
@@ -154,15 +156,15 @@ void ima_file_free(struct file *file)
 	ima_check_last_writer(iint, inode, file);
 	ima_check_last_writer(iint, inode, file);
 }
 }
 
 
-static int process_measurement(struct file *file, const char *filename,
-			       int mask, int function)
+static int process_measurement(struct file *file, int mask, int function,
+			       int opened)
 {
 {
 	struct inode *inode = file_inode(file);
 	struct inode *inode = file_inode(file);
 	struct integrity_iint_cache *iint;
 	struct integrity_iint_cache *iint;
 	struct ima_template_desc *template_desc;
 	struct ima_template_desc *template_desc;
 	char *pathbuf = NULL;
 	char *pathbuf = NULL;
 	const char *pathname = NULL;
 	const char *pathname = NULL;
-	int rc = -ENOMEM, action, must_appraise, _func;
+	int rc = -ENOMEM, action, must_appraise;
 	struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL;
 	struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL;
 	int xattr_len = 0;
 	int xattr_len = 0;
 
 
@@ -180,7 +182,8 @@ static int process_measurement(struct file *file, const char *filename,
 	must_appraise = action & IMA_APPRAISE;
 	must_appraise = action & IMA_APPRAISE;
 
 
 	/*  Is the appraise rule hook specific?  */
 	/*  Is the appraise rule hook specific?  */
-	_func = (action & IMA_FILE_APPRAISE) ? FILE_CHECK : function;
+	if (action & IMA_FILE_APPRAISE)
+		function = FILE_CHECK;
 
 
 	mutex_lock(&inode->i_mutex);
 	mutex_lock(&inode->i_mutex);
 
 
@@ -199,15 +202,13 @@ static int process_measurement(struct file *file, const char *filename,
 	/* Nothing to do, just return existing appraised status */
 	/* Nothing to do, just return existing appraised status */
 	if (!action) {
 	if (!action) {
 		if (must_appraise)
 		if (must_appraise)
-			rc = ima_get_cache_status(iint, _func);
+			rc = ima_get_cache_status(iint, function);
 		goto out_digsig;
 		goto out_digsig;
 	}
 	}
 
 
 	template_desc = ima_template_desc_current();
 	template_desc = ima_template_desc_current();
-	if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) {
-		if (action & IMA_APPRAISE_SUBMASK)
-			xattr_ptr = &xattr_value;
-	} else
+	if ((action & IMA_APPRAISE_SUBMASK) ||
+		    strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0)
 		xattr_ptr = &xattr_value;
 		xattr_ptr = &xattr_value;
 
 
 	rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len);
 	rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len);
@@ -217,14 +218,14 @@ static int process_measurement(struct file *file, const char *filename,
 		goto out_digsig;
 		goto out_digsig;
 	}
 	}
 
 
-	pathname = filename ?: ima_d_path(&file->f_path, &pathbuf);
+	pathname = ima_d_path(&file->f_path, &pathbuf);
 
 
 	if (action & IMA_MEASURE)
 	if (action & IMA_MEASURE)
 		ima_store_measurement(iint, file, pathname,
 		ima_store_measurement(iint, file, pathname,
 				      xattr_value, xattr_len);
 				      xattr_value, xattr_len);
 	if (action & IMA_APPRAISE_SUBMASK)
 	if (action & IMA_APPRAISE_SUBMASK)
-		rc = ima_appraise_measurement(_func, iint, file, pathname,
-					      xattr_value, xattr_len);
+		rc = ima_appraise_measurement(function, iint, file, pathname,
+					      xattr_value, xattr_len, opened);
 	if (action & IMA_AUDIT)
 	if (action & IMA_AUDIT)
 		ima_audit_measurement(iint, pathname);
 		ima_audit_measurement(iint, pathname);
 	kfree(pathbuf);
 	kfree(pathbuf);
@@ -253,7 +254,7 @@ out:
 int ima_file_mmap(struct file *file, unsigned long prot)
 int ima_file_mmap(struct file *file, unsigned long prot)
 {
 {
 	if (file && (prot & PROT_EXEC))
 	if (file && (prot & PROT_EXEC))
-		return process_measurement(file, NULL, MAY_EXEC, MMAP_CHECK);
+		return process_measurement(file, MAY_EXEC, MMAP_CHECK, 0);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -272,10 +273,7 @@ int ima_file_mmap(struct file *file, unsigned long prot)
  */
  */
 int ima_bprm_check(struct linux_binprm *bprm)
 int ima_bprm_check(struct linux_binprm *bprm)
 {
 {
-	return process_measurement(bprm->file,
-				   (strcmp(bprm->filename, bprm->interp) == 0) ?
-				   bprm->filename : bprm->interp,
-				   MAY_EXEC, BPRM_CHECK);
+	return process_measurement(bprm->file, MAY_EXEC, BPRM_CHECK, 0);
 }
 }
 
 
 /**
 /**
@@ -288,12 +286,12 @@ int ima_bprm_check(struct linux_binprm *bprm)
  * On success return 0.  On integrity appraisal error, assuming the file
  * On success return 0.  On integrity appraisal error, assuming the file
  * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
  * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
  */
  */
-int ima_file_check(struct file *file, int mask)
+int ima_file_check(struct file *file, int mask, int opened)
 {
 {
 	ima_rdwr_violation_check(file);
 	ima_rdwr_violation_check(file);
-	return process_measurement(file, NULL,
+	return process_measurement(file,
 				   mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
 				   mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
-				   FILE_CHECK);
+				   FILE_CHECK, opened);
 }
 }
 EXPORT_SYMBOL_GPL(ima_file_check);
 EXPORT_SYMBOL_GPL(ima_file_check);
 
 
@@ -316,7 +314,7 @@ int ima_module_check(struct file *file)
 #endif
 #endif
 		return 0;	/* We rely on module signature checking */
 		return 0;	/* We rely on module signature checking */
 	}
 	}
-	return process_measurement(file, NULL, MAY_EXEC, MODULE_CHECK);
+	return process_measurement(file, MAY_EXEC, MODULE_CHECK, 0);
 }
 }
 
 
 int ima_fw_from_file(struct file *file, char *buf, size_t size)
 int ima_fw_from_file(struct file *file, char *buf, size_t size)
@@ -327,7 +325,7 @@ int ima_fw_from_file(struct file *file, char *buf, size_t size)
 			return -EACCES;	/* INTEGRITY_UNKNOWN */
 			return -EACCES;	/* INTEGRITY_UNKNOWN */
 		return 0;
 		return 0;
 	}
 	}
-	return process_measurement(file, NULL, MAY_EXEC, FIRMWARE_CHECK);
+	return process_measurement(file, MAY_EXEC, FIRMWARE_CHECK, 0);
 }
 }
 
 
 static int __init init_ima(void)
 static int __init init_ima(void)

+ 5 - 25
security/integrity/ima/ima_template.c

@@ -152,24 +152,6 @@ out:
 	return result;
 	return result;
 }
 }
 
 
-static int init_defined_templates(void)
-{
-	int i = 0;
-	int result = 0;
-
-	/* Init defined templates. */
-	for (i = 0; i < ARRAY_SIZE(defined_templates); i++) {
-		struct ima_template_desc *template = &defined_templates[i];
-
-		result = template_desc_init_fields(template->fmt,
-						   &(template->fields),
-						   &(template->num_fields));
-		if (result < 0)
-			return result;
-	}
-	return result;
-}
-
 struct ima_template_desc *ima_template_desc_current(void)
 struct ima_template_desc *ima_template_desc_current(void)
 {
 {
 	if (!ima_template)
 	if (!ima_template)
@@ -178,13 +160,11 @@ struct ima_template_desc *ima_template_desc_current(void)
 	return ima_template;
 	return ima_template;
 }
 }
 
 
-int ima_init_template(void)
+int __init ima_init_template(void)
 {
 {
-	int result;
-
-	result = init_defined_templates();
-	if (result < 0)
-		return result;
+	struct ima_template_desc *template = ima_template_desc_current();
 
 
-	return 0;
+	return template_desc_init_fields(template->fmt,
+					 &(template->fields),
+					 &(template->num_fields));
 }
 }

+ 1 - 1
security/integrity/integrity.h

@@ -31,6 +31,7 @@
 #define IMA_DIGSIG		0x01000000
 #define IMA_DIGSIG		0x01000000
 #define IMA_DIGSIG_REQUIRED	0x02000000
 #define IMA_DIGSIG_REQUIRED	0x02000000
 #define IMA_PERMIT_DIRECTIO	0x04000000
 #define IMA_PERMIT_DIRECTIO	0x04000000
+#define IMA_NEW_FILE		0x08000000
 
 
 #define IMA_DO_MASK		(IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
 #define IMA_DO_MASK		(IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
 				 IMA_APPRAISE_SUBMASK)
 				 IMA_APPRAISE_SUBMASK)
@@ -116,7 +117,6 @@ struct integrity_iint_cache {
 /* rbtree tree calls to lookup, insert, delete
 /* rbtree tree calls to lookup, insert, delete
  * integrity data associated with an inode.
  * integrity data associated with an inode.
  */
  */
-struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
 struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
 struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
 
 
 #define INTEGRITY_KEYRING_EVM		0
 #define INTEGRITY_KEYRING_EVM		0