diff options
Diffstat (limited to 'ANDROID_3.4.5/security/integrity')
23 files changed, 0 insertions, 3209 deletions
diff --git a/ANDROID_3.4.5/security/integrity/Kconfig b/ANDROID_3.4.5/security/integrity/Kconfig deleted file mode 100644 index 5bd1cc1b..00000000 --- a/ANDROID_3.4.5/security/integrity/Kconfig +++ /dev/null @@ -1,21 +0,0 @@ -# -config INTEGRITY - def_bool y - depends on IMA || EVM - -config INTEGRITY_SIGNATURE - boolean "Digital signature verification using multiple keyrings" - depends on INTEGRITY && KEYS - default n - select SIGNATURE - help - This option enables digital signature verification support - using multiple keyrings. It defines separate keyrings for each - of the different use cases - evm, ima, and modules. - Different keyrings improves search performance, but also allow - to "lock" certain keyring to prevent adding new keys. - This is useful for evm and module keyrings, when keys are - usually only added from initramfs. - -source security/integrity/ima/Kconfig -source security/integrity/evm/Kconfig diff --git a/ANDROID_3.4.5/security/integrity/Makefile b/ANDROID_3.4.5/security/integrity/Makefile deleted file mode 100644 index d43799cc..00000000 --- a/ANDROID_3.4.5/security/integrity/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# Makefile for caching inode integrity data (iint) -# - -obj-$(CONFIG_INTEGRITY) += integrity.o -obj-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o - -integrity-y := iint.o - -subdir-$(CONFIG_IMA) += ima -obj-$(CONFIG_IMA) += ima/built-in.o -subdir-$(CONFIG_EVM) += evm -obj-$(CONFIG_EVM) += evm/built-in.o diff --git a/ANDROID_3.4.5/security/integrity/digsig.c b/ANDROID_3.4.5/security/integrity/digsig.c deleted file mode 100644 index 2dc167d7..00000000 --- a/ANDROID_3.4.5/security/integrity/digsig.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2011 Intel Corporation - * - * Author: - * Dmitry Kasatkin <dmitry.kasatkin@intel.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/err.h> -#include <linux/rbtree.h> -#include <linux/key-type.h> -#include <linux/digsig.h> - -#include "integrity.h" - -static struct key *keyring[INTEGRITY_KEYRING_MAX]; - -static const char *keyring_name[INTEGRITY_KEYRING_MAX] = { - "_evm", - "_module", - "_ima", -}; - -int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, - const char *digest, int digestlen) -{ - if (id >= INTEGRITY_KEYRING_MAX) - return -EINVAL; - - if (!keyring[id]) { - keyring[id] = - request_key(&key_type_keyring, keyring_name[id], NULL); - if (IS_ERR(keyring[id])) { - int err = PTR_ERR(keyring[id]); - pr_err("no %s keyring: %d\n", keyring_name[id], err); - keyring[id] = NULL; - return err; - } - } - - return digsig_verify(keyring[id], sig, siglen, digest, digestlen); -} diff --git a/ANDROID_3.4.5/security/integrity/evm/Kconfig b/ANDROID_3.4.5/security/integrity/evm/Kconfig deleted file mode 100644 index afbb59dd..00000000 --- a/ANDROID_3.4.5/security/integrity/evm/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -config EVM - boolean "EVM support" - depends on SECURITY && KEYS && (TRUSTED_KEYS=y || TRUSTED_KEYS=n) - select CRYPTO_HMAC - select CRYPTO_MD5 - select CRYPTO_SHA1 - select ENCRYPTED_KEYS - default n - help - EVM protects a file's security extended attributes against - integrity attacks. - - If you are unsure how to answer this question, answer N. diff --git a/ANDROID_3.4.5/security/integrity/evm/Makefile b/ANDROID_3.4.5/security/integrity/evm/Makefile deleted file mode 100644 index 7393c415..00000000 --- a/ANDROID_3.4.5/security/integrity/evm/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for building the Extended Verification Module(EVM) -# -obj-$(CONFIG_EVM) += evm.o - -evm-y := evm_main.o evm_crypto.o evm_secfs.o -evm-$(CONFIG_FS_POSIX_ACL) += evm_posix_acl.o diff --git a/ANDROID_3.4.5/security/integrity/evm/evm.h b/ANDROID_3.4.5/security/integrity/evm/evm.h deleted file mode 100644 index c885247e..00000000 --- a/ANDROID_3.4.5/security/integrity/evm/evm.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2005-2010 IBM Corporation - * - * Authors: - * Mimi Zohar <zohar@us.ibm.com> - * Kylene Hall <kjhall@us.ibm.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * File: evm.h - * - */ - -#ifndef __INTEGRITY_EVM_H -#define __INTEGRITY_EVM_H - -#include <linux/xattr.h> -#include <linux/security.h> - -#include "../integrity.h" - -extern int evm_initialized; -extern char *evm_hmac; -extern char *evm_hash; - -extern struct crypto_shash *hmac_tfm; -extern struct crypto_shash *hash_tfm; - -/* List of EVM protected security xattrs */ -extern char *evm_config_xattrnames[]; - -extern int evm_init_key(void); -extern int evm_update_evmxattr(struct dentry *dentry, - const char *req_xattr_name, - const char *req_xattr_value, - size_t req_xattr_value_len); -extern int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, - const char *req_xattr_value, - size_t req_xattr_value_len, char *digest); -extern int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name, - const char *req_xattr_value, - size_t req_xattr_value_len, char *digest); -extern int evm_init_hmac(struct inode *inode, const struct xattr *xattr, - char *hmac_val); -extern int evm_init_secfs(void); -extern void evm_cleanup_secfs(void); - -#endif diff --git a/ANDROID_3.4.5/security/integrity/evm/evm_crypto.c b/ANDROID_3.4.5/security/integrity/evm/evm_crypto.c deleted file mode 100644 index 49a464f5..00000000 --- a/ANDROID_3.4.5/security/integrity/evm/evm_crypto.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (C) 2005-2010 IBM Corporation - * - * Authors: - * Mimi Zohar <zohar@us.ibm.com> - * Kylene Hall <kjhall@us.ibm.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * File: evm_crypto.c - * Using root's kernel master key (kmk), calculate the HMAC - */ - -#include <linux/module.h> -#include <linux/crypto.h> -#include <linux/xattr.h> -#include <keys/encrypted-type.h> -#include <crypto/hash.h> -#include "evm.h" - -#define EVMKEY "evm-key" -#define MAX_KEY_SIZE 128 -static unsigned char evmkey[MAX_KEY_SIZE]; -static int evmkey_len = MAX_KEY_SIZE; - -struct crypto_shash *hmac_tfm; -struct crypto_shash *hash_tfm; - -static DEFINE_MUTEX(mutex); - -static struct shash_desc *init_desc(char type) -{ - long rc; - char *algo; - struct crypto_shash **tfm; - struct shash_desc *desc; - - if (type == EVM_XATTR_HMAC) { - tfm = &hmac_tfm; - algo = evm_hmac; - } else { - tfm = &hash_tfm; - algo = evm_hash; - } - - if (*tfm == NULL) { - mutex_lock(&mutex); - if (*tfm) - goto out; - *tfm = crypto_alloc_shash(algo, 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(*tfm)) { - rc = PTR_ERR(*tfm); - pr_err("Can not allocate %s (reason: %ld)\n", algo, rc); - *tfm = NULL; - mutex_unlock(&mutex); - return ERR_PTR(rc); - } - if (type == EVM_XATTR_HMAC) { - rc = crypto_shash_setkey(*tfm, evmkey, evmkey_len); - if (rc) { - crypto_free_shash(*tfm); - *tfm = NULL; - mutex_unlock(&mutex); - return ERR_PTR(rc); - } - } -out: - mutex_unlock(&mutex); - } - - desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(*tfm), - GFP_KERNEL); - if (!desc) - return ERR_PTR(-ENOMEM); - - desc->tfm = *tfm; - desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; - - rc = crypto_shash_init(desc); - if (rc) { - kfree(desc); - return ERR_PTR(rc); - } - return desc; -} - -/* Protect against 'cutting & pasting' security.evm xattr, include inode - * specific info. - * - * (Additional directory/file metadata needs to be added for more complete - * protection.) - */ -static void hmac_add_misc(struct shash_desc *desc, struct inode *inode, - char *digest) -{ - struct h_misc { - unsigned long ino; - __u32 generation; - uid_t uid; - gid_t gid; - umode_t mode; - } hmac_misc; - - memset(&hmac_misc, 0, sizeof hmac_misc); - hmac_misc.ino = inode->i_ino; - hmac_misc.generation = inode->i_generation; - hmac_misc.uid = inode->i_uid; - hmac_misc.gid = inode->i_gid; - hmac_misc.mode = inode->i_mode; - crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof hmac_misc); - crypto_shash_final(desc, digest); -} - -/* - * Calculate the HMAC value across the set of protected security xattrs. - * - * Instead of retrieving the requested xattr, for performance, calculate - * the hmac using the requested xattr value. Don't alloc/free memory for - * each xattr, but attempt to re-use the previously allocated memory. - */ -static int evm_calc_hmac_or_hash(struct dentry *dentry, - const char *req_xattr_name, - const char *req_xattr_value, - size_t req_xattr_value_len, - char type, char *digest) -{ - struct inode *inode = dentry->d_inode; - struct shash_desc *desc; - char **xattrname; - size_t xattr_size = 0; - char *xattr_value = NULL; - int error; - int size; - - if (!inode->i_op || !inode->i_op->getxattr) - return -EOPNOTSUPP; - desc = init_desc(type); - if (IS_ERR(desc)) - return PTR_ERR(desc); - - error = -ENODATA; - for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) { - if ((req_xattr_name && req_xattr_value) - && !strcmp(*xattrname, req_xattr_name)) { - error = 0; - crypto_shash_update(desc, (const u8 *)req_xattr_value, - req_xattr_value_len); - continue; - } - size = vfs_getxattr_alloc(dentry, *xattrname, - &xattr_value, xattr_size, GFP_NOFS); - if (size == -ENOMEM) { - error = -ENOMEM; - goto out; - } - if (size < 0) - continue; - - error = 0; - xattr_size = size; - crypto_shash_update(desc, (const u8 *)xattr_value, xattr_size); - } - hmac_add_misc(desc, inode, digest); - -out: - kfree(xattr_value); - kfree(desc); - return error; -} - -int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, - const char *req_xattr_value, size_t req_xattr_value_len, - char *digest) -{ - return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value, - req_xattr_value_len, EVM_XATTR_HMAC, digest); -} - -int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name, - const char *req_xattr_value, size_t req_xattr_value_len, - char *digest) -{ - return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value, - req_xattr_value_len, IMA_XATTR_DIGEST, digest); -} - -/* - * Calculate the hmac and update security.evm xattr - * - * Expects to be called with i_mutex locked. - */ -int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name, - const char *xattr_value, size_t xattr_value_len) -{ - struct inode *inode = dentry->d_inode; - struct evm_ima_xattr_data xattr_data; - int rc = 0; - - rc = evm_calc_hmac(dentry, xattr_name, xattr_value, - xattr_value_len, xattr_data.digest); - if (rc == 0) { - xattr_data.type = EVM_XATTR_HMAC; - rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM, - &xattr_data, - sizeof(xattr_data), 0); - } - else if (rc == -ENODATA) - rc = inode->i_op->removexattr(dentry, XATTR_NAME_EVM); - return rc; -} - -int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr, - char *hmac_val) -{ - struct shash_desc *desc; - - desc = init_desc(EVM_XATTR_HMAC); - if (IS_ERR(desc)) { - printk(KERN_INFO "init_desc failed\n"); - return PTR_ERR(desc); - } - - crypto_shash_update(desc, lsm_xattr->value, lsm_xattr->value_len); - hmac_add_misc(desc, inode, hmac_val); - kfree(desc); - return 0; -} - -/* - * Get the key from the TPM for the SHA1-HMAC - */ -int evm_init_key(void) -{ - struct key *evm_key; - struct encrypted_key_payload *ekp; - int rc = 0; - - evm_key = request_key(&key_type_encrypted, EVMKEY, NULL); - if (IS_ERR(evm_key)) - return -ENOENT; - - down_read(&evm_key->sem); - ekp = evm_key->payload.data; - if (ekp->decrypted_datalen > MAX_KEY_SIZE) { - rc = -EINVAL; - goto out; - } - memcpy(evmkey, ekp->decrypted_data, ekp->decrypted_datalen); -out: - /* burn the original key contents */ - memset(ekp->decrypted_data, 0, ekp->decrypted_datalen); - up_read(&evm_key->sem); - key_put(evm_key); - return rc; -} diff --git a/ANDROID_3.4.5/security/integrity/evm/evm_main.c b/ANDROID_3.4.5/security/integrity/evm/evm_main.c deleted file mode 100644 index 89015014..00000000 --- a/ANDROID_3.4.5/security/integrity/evm/evm_main.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Copyright (C) 2005-2010 IBM Corporation - * - * Author: - * Mimi Zohar <zohar@us.ibm.com> - * Kylene Hall <kjhall@us.ibm.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * File: evm_main.c - * implements evm_inode_setxattr, evm_inode_post_setxattr, - * evm_inode_removexattr, and evm_verifyxattr - */ - -#include <linux/module.h> -#include <linux/crypto.h> -#include <linux/xattr.h> -#include <linux/integrity.h> -#include <linux/evm.h> -#include <crypto/hash.h> -#include "evm.h" - -int evm_initialized; - -char *evm_hmac = "hmac(sha1)"; -char *evm_hash = "sha1"; - -char *evm_config_xattrnames[] = { -#ifdef CONFIG_SECURITY_SELINUX - XATTR_NAME_SELINUX, -#endif -#ifdef CONFIG_SECURITY_SMACK - XATTR_NAME_SMACK, -#endif - XATTR_NAME_CAPS, - NULL -}; - -static int evm_fixmode; -static int __init evm_set_fixmode(char *str) -{ - if (strncmp(str, "fix", 3) == 0) - evm_fixmode = 1; - return 0; -} -__setup("evm=", evm_set_fixmode); - -static int evm_find_protected_xattrs(struct dentry *dentry) -{ - struct inode *inode = dentry->d_inode; - char **xattr; - int error; - int count = 0; - - if (!inode->i_op || !inode->i_op->getxattr) - return -EOPNOTSUPP; - - for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) { - error = inode->i_op->getxattr(dentry, *xattr, NULL, 0); - if (error < 0) { - if (error == -ENODATA) - continue; - return error; - } - count++; - } - - return count; -} - -/* - * evm_verify_hmac - calculate and compare the HMAC with the EVM xattr - * - * Compute the HMAC on the dentry's protected set of extended attributes - * and compare it against the stored security.evm xattr. - * - * For performance: - * - use the previoulsy retrieved xattr value and length to calculate the - * HMAC.) - * - cache the verification result in the iint, when available. - * - * Returns integrity status - */ -static enum integrity_status evm_verify_hmac(struct dentry *dentry, - const char *xattr_name, - char *xattr_value, - size_t xattr_value_len, - struct integrity_iint_cache *iint) -{ - struct evm_ima_xattr_data *xattr_data = NULL; - struct evm_ima_xattr_data calc; - enum integrity_status evm_status = INTEGRITY_PASS; - int rc, xattr_len; - - if (iint && iint->evm_status == INTEGRITY_PASS) - return iint->evm_status; - - /* if status is not PASS, try to check again - against -ENOMEM */ - - /* first need to know the sig type */ - rc = vfs_getxattr_alloc(dentry, XATTR_NAME_EVM, (char **)&xattr_data, 0, - GFP_NOFS); - if (rc <= 0) { - if (rc == 0) - evm_status = INTEGRITY_FAIL; /* empty */ - else if (rc == -ENODATA) { - rc = evm_find_protected_xattrs(dentry); - if (rc > 0) - evm_status = INTEGRITY_NOLABEL; - else if (rc == 0) - evm_status = INTEGRITY_NOXATTRS; /* new file */ - } - goto out; - } - - xattr_len = rc - 1; - - /* check value type */ - switch (xattr_data->type) { - case EVM_XATTR_HMAC: - rc = evm_calc_hmac(dentry, xattr_name, xattr_value, - xattr_value_len, calc.digest); - if (rc) - break; - rc = memcmp(xattr_data->digest, calc.digest, - sizeof(calc.digest)); - if (rc) - rc = -EINVAL; - break; - case EVM_IMA_XATTR_DIGSIG: - rc = evm_calc_hash(dentry, xattr_name, xattr_value, - xattr_value_len, calc.digest); - if (rc) - break; - rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM, - xattr_data->digest, xattr_len, - calc.digest, sizeof(calc.digest)); - if (!rc) { - /* we probably want to replace rsa with hmac here */ - evm_update_evmxattr(dentry, xattr_name, xattr_value, - xattr_value_len); - } - break; - default: - rc = -EINVAL; - break; - } - - if (rc) - evm_status = (rc == -ENODATA) ? - INTEGRITY_NOXATTRS : INTEGRITY_FAIL; -out: - if (iint) - iint->evm_status = evm_status; - kfree(xattr_data); - return evm_status; -} - -static int evm_protected_xattr(const char *req_xattr_name) -{ - char **xattrname; - int namelen; - int found = 0; - - namelen = strlen(req_xattr_name); - for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) { - if ((strlen(*xattrname) == namelen) - && (strncmp(req_xattr_name, *xattrname, namelen) == 0)) { - found = 1; - break; - } - if (strncmp(req_xattr_name, - *xattrname + XATTR_SECURITY_PREFIX_LEN, - strlen(req_xattr_name)) == 0) { - found = 1; - break; - } - } - return found; -} - -/** - * evm_verifyxattr - verify the integrity of the requested xattr - * @dentry: object of the verify xattr - * @xattr_name: requested xattr - * @xattr_value: requested xattr value - * @xattr_value_len: requested xattr value length - * - * Calculate the HMAC for the given dentry and verify it against the stored - * security.evm xattr. For performance, use the xattr value and length - * previously retrieved to calculate the HMAC. - * - * Returns the xattr integrity status. - * - * This function requires the caller to lock the inode's i_mutex before it - * is executed. - */ -enum integrity_status evm_verifyxattr(struct dentry *dentry, - const char *xattr_name, - void *xattr_value, size_t xattr_value_len, - struct integrity_iint_cache *iint) -{ - if (!evm_initialized || !evm_protected_xattr(xattr_name)) - return INTEGRITY_UNKNOWN; - - if (!iint) { - iint = integrity_iint_find(dentry->d_inode); - if (!iint) - return INTEGRITY_UNKNOWN; - } - return evm_verify_hmac(dentry, xattr_name, xattr_value, - xattr_value_len, iint); -} -EXPORT_SYMBOL_GPL(evm_verifyxattr); - -/* - * evm_verify_current_integrity - verify the dentry's metadata integrity - * @dentry: pointer to the affected dentry - * - * Verify and return the dentry's metadata integrity. The exceptions are - * before EVM is initialized or in 'fix' mode. - */ -static enum integrity_status evm_verify_current_integrity(struct dentry *dentry) -{ - struct inode *inode = dentry->d_inode; - - if (!evm_initialized || !S_ISREG(inode->i_mode) || evm_fixmode) - return 0; - return evm_verify_hmac(dentry, NULL, NULL, 0, NULL); -} - -/* - * evm_protect_xattr - protect the EVM extended attribute - * - * Prevent security.evm from being modified or removed without the - * necessary permissions or when the existing value is invalid. - * - * The posix xattr acls are 'system' prefixed, which normally would not - * affect security.evm. An interesting side affect of writing posix xattr - * acls is their modifying of the i_mode, which is included in security.evm. - * For posix xattr acls only, permit security.evm, even if it currently - * doesn't exist, to be updated. - */ -static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name, - const void *xattr_value, size_t xattr_value_len) -{ - enum integrity_status evm_status; - - if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) { - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - } else if (!evm_protected_xattr(xattr_name)) { - if (!posix_xattr_acl(xattr_name)) - return 0; - evm_status = evm_verify_current_integrity(dentry); - if ((evm_status == INTEGRITY_PASS) || - (evm_status == INTEGRITY_NOXATTRS)) - return 0; - return -EPERM; - } - evm_status = evm_verify_current_integrity(dentry); - return evm_status == INTEGRITY_PASS ? 0 : -EPERM; -} - -/** - * evm_inode_setxattr - protect the EVM extended attribute - * @dentry: pointer to the affected dentry - * @xattr_name: pointer to the affected extended attribute name - * @xattr_value: pointer to the new extended attribute value - * @xattr_value_len: pointer to the new extended attribute value length - * - * Updating 'security.evm' requires CAP_SYS_ADMIN privileges and that - * the current value is valid. - */ -int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name, - const void *xattr_value, size_t xattr_value_len) -{ - return evm_protect_xattr(dentry, xattr_name, xattr_value, - xattr_value_len); -} - -/** - * evm_inode_removexattr - protect the EVM extended attribute - * @dentry: pointer to the affected dentry - * @xattr_name: pointer to the affected extended attribute name - * - * Removing 'security.evm' requires CAP_SYS_ADMIN privileges and that - * the current value is valid. - */ -int evm_inode_removexattr(struct dentry *dentry, const char *xattr_name) -{ - return evm_protect_xattr(dentry, xattr_name, NULL, 0); -} - -/** - * evm_inode_post_setxattr - update 'security.evm' to reflect the changes - * @dentry: pointer to the affected dentry - * @xattr_name: pointer to the affected extended attribute name - * @xattr_value: pointer to the new extended attribute value - * @xattr_value_len: pointer to the new extended attribute value length - * - * Update the HMAC stored in 'security.evm' to reflect the change. - * - * No need to take the i_mutex lock here, as this function is called from - * __vfs_setxattr_noperm(). The caller of which has taken the inode's - * i_mutex lock. - */ -void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name, - const void *xattr_value, size_t xattr_value_len) -{ - if (!evm_initialized || (!evm_protected_xattr(xattr_name) - && !posix_xattr_acl(xattr_name))) - return; - - evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len); - return; -} - -/** - * evm_inode_post_removexattr - update 'security.evm' after removing the xattr - * @dentry: pointer to the affected dentry - * @xattr_name: pointer to the affected extended attribute name - * - * Update the HMAC stored in 'security.evm' to reflect removal of the xattr. - */ -void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name) -{ - struct inode *inode = dentry->d_inode; - - if (!evm_initialized || !evm_protected_xattr(xattr_name)) - return; - - mutex_lock(&inode->i_mutex); - evm_update_evmxattr(dentry, xattr_name, NULL, 0); - mutex_unlock(&inode->i_mutex); - return; -} - -/** - * evm_inode_setattr - prevent updating an invalid EVM extended attribute - * @dentry: pointer to the affected dentry - */ -int evm_inode_setattr(struct dentry *dentry, struct iattr *attr) -{ - unsigned int ia_valid = attr->ia_valid; - enum integrity_status evm_status; - - if (!(ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))) - return 0; - evm_status = evm_verify_current_integrity(dentry); - if ((evm_status == INTEGRITY_PASS) || - (evm_status == INTEGRITY_NOXATTRS)) - return 0; - return -EPERM; -} - -/** - * evm_inode_post_setattr - update 'security.evm' after modifying metadata - * @dentry: pointer to the affected dentry - * @ia_valid: for the UID and GID status - * - * For now, update the HMAC stored in 'security.evm' to reflect UID/GID - * changes. - * - * This function is called from notify_change(), which expects the caller - * to lock the inode's i_mutex. - */ -void evm_inode_post_setattr(struct dentry *dentry, int ia_valid) -{ - if (!evm_initialized) - return; - - if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)) - evm_update_evmxattr(dentry, NULL, NULL, 0); - return; -} - -/* - * evm_inode_init_security - initializes security.evm - */ -int evm_inode_init_security(struct inode *inode, - const struct xattr *lsm_xattr, - struct xattr *evm_xattr) -{ - struct evm_ima_xattr_data *xattr_data; - int rc; - - if (!evm_initialized || !evm_protected_xattr(lsm_xattr->name)) - return 0; - - xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS); - if (!xattr_data) - return -ENOMEM; - - xattr_data->type = EVM_XATTR_HMAC; - rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest); - if (rc < 0) - goto out; - - evm_xattr->value = xattr_data; - evm_xattr->value_len = sizeof(*xattr_data); - evm_xattr->name = kstrdup(XATTR_EVM_SUFFIX, GFP_NOFS); - return 0; -out: - kfree(xattr_data); - return rc; -} -EXPORT_SYMBOL_GPL(evm_inode_init_security); - -static int __init init_evm(void) -{ - int error; - - error = evm_init_secfs(); - if (error < 0) { - printk(KERN_INFO "EVM: Error registering secfs\n"); - goto err; - } - - return 0; -err: - return error; -} - -static void __exit cleanup_evm(void) -{ - evm_cleanup_secfs(); - if (hmac_tfm) - crypto_free_shash(hmac_tfm); - if (hash_tfm) - crypto_free_shash(hash_tfm); -} - -/* - * evm_display_config - list the EVM protected security extended attributes - */ -static int __init evm_display_config(void) -{ - char **xattrname; - - for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) - printk(KERN_INFO "EVM: %s\n", *xattrname); - return 0; -} - -pure_initcall(evm_display_config); -late_initcall(init_evm); - -MODULE_DESCRIPTION("Extended Verification Module"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/security/integrity/evm/evm_posix_acl.c b/ANDROID_3.4.5/security/integrity/evm/evm_posix_acl.c deleted file mode 100644 index b1753e98..00000000 --- a/ANDROID_3.4.5/security/integrity/evm/evm_posix_acl.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2011 IBM Corporation - * - * Author: - * Mimi Zohar <zohar@us.ibm.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - */ - -#include <linux/module.h> -#include <linux/xattr.h> - -int posix_xattr_acl(char *xattr) -{ - int xattr_len = strlen(xattr); - - if ((strlen(XATTR_NAME_POSIX_ACL_ACCESS) == xattr_len) - && (strncmp(XATTR_NAME_POSIX_ACL_ACCESS, xattr, xattr_len) == 0)) - return 1; - if ((strlen(XATTR_NAME_POSIX_ACL_DEFAULT) == xattr_len) - && (strncmp(XATTR_NAME_POSIX_ACL_DEFAULT, xattr, xattr_len) == 0)) - return 1; - return 0; -} diff --git a/ANDROID_3.4.5/security/integrity/evm/evm_secfs.c b/ANDROID_3.4.5/security/integrity/evm/evm_secfs.c deleted file mode 100644 index ac762995..00000000 --- a/ANDROID_3.4.5/security/integrity/evm/evm_secfs.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2010 IBM Corporation - * - * Authors: - * Mimi Zohar <zohar@us.ibm.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * File: evm_secfs.c - * - Used to signal when key is on keyring - * - Get the key and enable EVM - */ - -#include <linux/uaccess.h> -#include <linux/module.h> -#include "evm.h" - -static struct dentry *evm_init_tpm; - -/** - * evm_read_key - read() for <securityfs>/evm - * - * @filp: file pointer, not actually used - * @buf: where to put the result - * @count: maximum to send along - * @ppos: where to start - * - * Returns number of bytes read or error code, as appropriate - */ -static ssize_t evm_read_key(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - char temp[80]; - ssize_t rc; - - if (*ppos != 0) - return 0; - - sprintf(temp, "%d", evm_initialized); - rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); - - return rc; -} - -/** - * evm_write_key - write() for <securityfs>/evm - * @file: file pointer, not actually used - * @buf: where to get the data from - * @count: bytes sent - * @ppos: where to start - * - * Used to signal that key is on the kernel key ring. - * - get the integrity hmac key from the kernel key ring - * - create list of hmac protected extended attributes - * Returns number of bytes written or error code, as appropriate - */ -static ssize_t evm_write_key(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - char temp[80]; - int i, error; - - if (!capable(CAP_SYS_ADMIN) || evm_initialized) - return -EPERM; - - if (count >= sizeof(temp) || count == 0) - return -EINVAL; - - if (copy_from_user(temp, buf, count) != 0) - return -EFAULT; - - temp[count] = '\0'; - - if ((sscanf(temp, "%d", &i) != 1) || (i != 1)) - return -EINVAL; - - error = evm_init_key(); - if (!error) { - evm_initialized = 1; - pr_info("EVM: initialized\n"); - } else - pr_err("EVM: initialization failed\n"); - return count; -} - -static const struct file_operations evm_key_ops = { - .read = evm_read_key, - .write = evm_write_key, -}; - -int __init evm_init_secfs(void) -{ - int error = 0; - - evm_init_tpm = securityfs_create_file("evm", S_IRUSR | S_IRGRP, - NULL, NULL, &evm_key_ops); - if (!evm_init_tpm || IS_ERR(evm_init_tpm)) - error = -EFAULT; - return error; -} - -void __exit evm_cleanup_secfs(void) -{ - if (evm_init_tpm) - securityfs_remove(evm_init_tpm); -} diff --git a/ANDROID_3.4.5/security/integrity/iint.c b/ANDROID_3.4.5/security/integrity/iint.c deleted file mode 100644 index 399641c3..00000000 --- a/ANDROID_3.4.5/security/integrity/iint.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2008 IBM Corporation - * - * Authors: - * Mimi Zohar <zohar@us.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * File: integrity_iint.c - * - implements the integrity hooks: integrity_inode_alloc, - * integrity_inode_free - * - cache integrity information associated with an inode - * using a rbtree tree. - */ -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/spinlock.h> -#include <linux/rbtree.h> -#include "integrity.h" - -static struct rb_root integrity_iint_tree = RB_ROOT; -static DEFINE_SPINLOCK(integrity_iint_lock); -static struct kmem_cache *iint_cache __read_mostly; - -int iint_initialized; - -/* - * __integrity_iint_find - return the iint associated with an inode - */ -static struct integrity_iint_cache *__integrity_iint_find(struct inode *inode) -{ - struct integrity_iint_cache *iint; - struct rb_node *n = integrity_iint_tree.rb_node; - - assert_spin_locked(&integrity_iint_lock); - - while (n) { - iint = rb_entry(n, struct integrity_iint_cache, rb_node); - - if (inode < iint->inode) - n = n->rb_left; - else if (inode > iint->inode) - n = n->rb_right; - else - break; - } - if (!n) - return NULL; - - return iint; -} - -/* - * integrity_iint_find - return the iint associated with an inode - */ -struct integrity_iint_cache *integrity_iint_find(struct inode *inode) -{ - struct integrity_iint_cache *iint; - - if (!IS_IMA(inode)) - return NULL; - - spin_lock(&integrity_iint_lock); - iint = __integrity_iint_find(inode); - spin_unlock(&integrity_iint_lock); - - return iint; -} - -static void iint_free(struct integrity_iint_cache *iint) -{ - iint->version = 0; - iint->flags = 0UL; - iint->evm_status = INTEGRITY_UNKNOWN; - kmem_cache_free(iint_cache, iint); -} - -/** - * integrity_inode_alloc - allocate an iint associated with an inode - * @inode: pointer to the inode - */ -int integrity_inode_alloc(struct inode *inode) -{ - struct rb_node **p; - struct rb_node *new_node, *parent = NULL; - struct integrity_iint_cache *new_iint, *test_iint; - int rc; - - new_iint = kmem_cache_alloc(iint_cache, GFP_NOFS); - if (!new_iint) - return -ENOMEM; - - new_iint->inode = inode; - new_node = &new_iint->rb_node; - - mutex_lock(&inode->i_mutex); /* i_flags */ - spin_lock(&integrity_iint_lock); - - p = &integrity_iint_tree.rb_node; - while (*p) { - parent = *p; - test_iint = rb_entry(parent, struct integrity_iint_cache, - rb_node); - rc = -EEXIST; - if (inode < test_iint->inode) - p = &(*p)->rb_left; - else if (inode > test_iint->inode) - p = &(*p)->rb_right; - else - goto out_err; - } - - inode->i_flags |= S_IMA; - rb_link_node(new_node, parent, p); - rb_insert_color(new_node, &integrity_iint_tree); - - spin_unlock(&integrity_iint_lock); - mutex_unlock(&inode->i_mutex); /* i_flags */ - - return 0; -out_err: - spin_unlock(&integrity_iint_lock); - mutex_unlock(&inode->i_mutex); /* i_flags */ - iint_free(new_iint); - - return rc; -} - -/** - * integrity_inode_free - called on security_inode_free - * @inode: pointer to the inode - * - * Free the integrity information(iint) associated with an inode. - */ -void integrity_inode_free(struct inode *inode) -{ - struct integrity_iint_cache *iint; - - if (!IS_IMA(inode)) - return; - - spin_lock(&integrity_iint_lock); - iint = __integrity_iint_find(inode); - rb_erase(&iint->rb_node, &integrity_iint_tree); - spin_unlock(&integrity_iint_lock); - - iint_free(iint); -} - -static void init_once(void *foo) -{ - struct integrity_iint_cache *iint = foo; - - memset(iint, 0, sizeof *iint); - iint->version = 0; - iint->flags = 0UL; - mutex_init(&iint->mutex); - iint->evm_status = INTEGRITY_UNKNOWN; -} - -static int __init integrity_iintcache_init(void) -{ - iint_cache = - kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache), - 0, SLAB_PANIC, init_once); - iint_initialized = 1; - return 0; -} -security_initcall(integrity_iintcache_init); diff --git a/ANDROID_3.4.5/security/integrity/ima/Kconfig b/ANDROID_3.4.5/security/integrity/ima/Kconfig deleted file mode 100644 index 35664fe6..00000000 --- a/ANDROID_3.4.5/security/integrity/ima/Kconfig +++ /dev/null @@ -1,56 +0,0 @@ -# IBM Integrity Measurement Architecture -# -config IMA - bool "Integrity Measurement Architecture(IMA)" - depends on SECURITY - select INTEGRITY - select SECURITYFS - select CRYPTO - select CRYPTO_HMAC - select CRYPTO_MD5 - select CRYPTO_SHA1 - select TCG_TPM if HAS_IOMEM && !UML - select TCG_TIS if TCG_TPM && X86 - help - The Trusted Computing Group(TCG) runtime Integrity - Measurement Architecture(IMA) maintains a list of hash - values of executables and other sensitive system files, - as they are read or executed. If an attacker manages - to change the contents of an important system file - being measured, we can tell. - - If your system has a TPM chip, then IMA also maintains - an aggregate integrity value over this list inside the - TPM hardware, so that the TPM can prove to a third party - whether or not critical system files have been modified. - Read <http://www.usenix.org/events/sec04/tech/sailer.html> - to learn more about IMA. - If unsure, say N. - -config IMA_MEASURE_PCR_IDX - int - depends on IMA - range 8 14 - default 10 - help - IMA_MEASURE_PCR_IDX determines the TPM PCR register index - that IMA uses to maintain the integrity aggregate of the - measurement list. If unsure, use the default 10. - -config IMA_AUDIT - bool - depends on IMA - default y - help - This option adds a kernel parameter 'ima_audit', which - allows informational auditing messages to be enabled - at boot. If this option is selected, informational integrity - auditing messages can be enabled with 'ima_audit=1' on - the kernel command line. - -config IMA_LSM_RULES - bool - depends on IMA && AUDIT && (SECURITY_SELINUX || SECURITY_SMACK) - default y - help - Disabling this option will disregard LSM based policy rules. diff --git a/ANDROID_3.4.5/security/integrity/ima/Makefile b/ANDROID_3.4.5/security/integrity/ima/Makefile deleted file mode 100644 index 5690c021..00000000 --- a/ANDROID_3.4.5/security/integrity/ima/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for building Trusted Computing Group's(TCG) runtime Integrity -# Measurement Architecture(IMA). -# - -obj-$(CONFIG_IMA) += ima.o - -ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ - ima_policy.o ima_audit.o diff --git a/ANDROID_3.4.5/security/integrity/ima/ima.h b/ANDROID_3.4.5/security/integrity/ima/ima.h deleted file mode 100644 index 3ccf7aca..00000000 --- a/ANDROID_3.4.5/security/integrity/ima/ima.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2005,2006,2007,2008 IBM Corporation - * - * Authors: - * Reiner Sailer <sailer@watson.ibm.com> - * Mimi Zohar <zohar@us.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * File: ima.h - * internal Integrity Measurement Architecture (IMA) definitions - */ - -#ifndef __LINUX_IMA_H -#define __LINUX_IMA_H - -#include <linux/types.h> -#include <linux/crypto.h> -#include <linux/security.h> -#include <linux/hash.h> -#include <linux/tpm.h> -#include <linux/audit.h> - -#include "../integrity.h" - -enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII }; -enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; - -/* digest size for IMA, fits SHA1 or MD5 */ -#define IMA_DIGEST_SIZE SHA1_DIGEST_SIZE -#define IMA_EVENT_NAME_LEN_MAX 255 - -#define IMA_HASH_BITS 9 -#define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS) - -/* set during initialization */ -extern int ima_initialized; -extern int ima_used_chip; -extern char *ima_hash; - -/* IMA inode template definition */ -struct ima_template_data { - u8 digest[IMA_DIGEST_SIZE]; /* sha1/md5 measurement hash */ - char file_name[IMA_EVENT_NAME_LEN_MAX + 1]; /* name + \0 */ -}; - -struct ima_template_entry { - u8 digest[IMA_DIGEST_SIZE]; /* sha1 or md5 measurement hash */ - const char *template_name; - int template_len; - struct ima_template_data template; -}; - -struct ima_queue_entry { - struct hlist_node hnext; /* place in hash collision list */ - struct list_head later; /* place in ima_measurements list */ - struct ima_template_entry *entry; -}; -extern struct list_head ima_measurements; /* list of all measurements */ - -/* declarations */ -void integrity_audit_msg(int audit_msgno, struct inode *inode, - const unsigned char *fname, const char *op, - const char *cause, int result, int info); - -/* Internal IMA function definitions */ -int ima_init(void); -void ima_cleanup(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, - const char *op, struct inode *inode); -int ima_calc_hash(struct file *file, char *digest); -int ima_calc_template_hash(int template_len, void *template, char *digest); -int ima_calc_boot_aggregate(char *digest); -void ima_add_violation(struct inode *inode, const unsigned char *filename, - const char *op, const char *cause); - -/* - * used to protect h_table and sha_table - */ -extern spinlock_t ima_queue_lock; - -struct ima_h_table { - atomic_long_t len; /* number of stored measurements in the list */ - atomic_long_t violations; - struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE]; -}; -extern struct ima_h_table ima_htable; - -static inline unsigned long ima_hash_key(u8 *digest) -{ - return hash_long(*digest, IMA_HASH_BITS); -} - -/* LIM API function definitions */ -int ima_must_measure(struct inode *inode, int mask, int function); -int ima_collect_measurement(struct integrity_iint_cache *iint, - struct file *file); -void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, - const unsigned char *filename); -int ima_store_template(struct ima_template_entry *entry, int violation, - struct inode *inode); -void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show); - -/* 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 */ -enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK }; - -int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask); -void ima_init_policy(void); -void ima_update_policy(void); -ssize_t ima_parse_add_rule(char *); -void ima_delete_rules(void); - -/* LSM based policy rules require audit */ -#ifdef CONFIG_IMA_LSM_RULES - -#define security_filter_rule_init security_audit_rule_init -#define security_filter_rule_match security_audit_rule_match - -#else - -static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr, - void **lsmrule) -{ - return -EINVAL; -} - -static inline int security_filter_rule_match(u32 secid, u32 field, u32 op, - void *lsmrule, - struct audit_context *actx) -{ - return -EINVAL; -} -#endif /* CONFIG_IMA_LSM_RULES */ -#endif diff --git a/ANDROID_3.4.5/security/integrity/ima/ima_api.c b/ANDROID_3.4.5/security/integrity/ima/ima_api.c deleted file mode 100644 index 88a2788b..00000000 --- a/ANDROID_3.4.5/security/integrity/ima/ima_api.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2008 IBM Corporation - * - * Author: Mimi Zohar <zohar@us.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * File: ima_api.c - * Implements must_measure, collect_measurement, store_measurement, - * and store_template. - */ -#include <linux/module.h> -#include <linux/slab.h> - -#include "ima.h" -static const char *IMA_TEMPLATE_NAME = "ima"; - -/* - * ima_store_template - store ima template measurements - * - * Calculate the hash of a template entry, add the template entry - * to an ordered list of measurement entries maintained inside the kernel, - * and also update the aggregate integrity value (maintained inside the - * configured TPM PCR) over the hashes of the current list of measurement - * entries. - * - * Applications retrieve the current kernel-held measurement list through - * the securityfs entries in /sys/kernel/security/ima. The signed aggregate - * TPM PCR (called quote) can be retrieved using a TPM user space library - * and is used to validate the measurement list. - * - * Returns 0 on success, error code otherwise - */ -int ima_store_template(struct ima_template_entry *entry, - int violation, struct inode *inode) -{ - const char *op = "add_template_measure"; - const char *audit_cause = "hashing_error"; - int result; - - memset(entry->digest, 0, sizeof(entry->digest)); - entry->template_name = IMA_TEMPLATE_NAME; - entry->template_len = sizeof(entry->template); - - if (!violation) { - result = ima_calc_template_hash(entry->template_len, - &entry->template, - entry->digest); - if (result < 0) { - integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, - entry->template_name, op, - audit_cause, result, 0); - return result; - } - } - result = ima_add_template_entry(entry, violation, op, inode); - return result; -} - -/* - * ima_add_violation - add violation to measurement list. - * - * Violations are flagged in the measurement list with zero hash values. - * By extending the PCR with 0xFF's instead of with zeroes, the PCR - * value is invalidated. - */ -void ima_add_violation(struct inode *inode, const unsigned char *filename, - const char *op, const char *cause) -{ - struct ima_template_entry *entry; - int violation = 1; - int result; - - /* can overflow, only indicator */ - atomic_long_inc(&ima_htable.violations); - - entry = kmalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) { - result = -ENOMEM; - goto err_out; - } - memset(&entry->template, 0, sizeof(entry->template)); - strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX); - result = ima_store_template(entry, violation, inode); - if (result < 0) - kfree(entry); -err_out: - integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, - op, cause, result, 0); -} - -/** - * ima_must_measure - measure decision based on policy. - * @inode: pointer to inode to measure - * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE) - * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP) - * - * The policy is defined in terms of keypairs: - * subj=, obj=, type=, func=, mask=, fsmagic= - * subj,obj, and type: are LSM specific. - * func: FILE_CHECK | BPRM_CHECK | FILE_MMAP - * mask: contains the permission mask - * fsmagic: hex value - * - * Return 0 to measure. For matching a DONT_MEASURE policy, no policy, - * or other error, return an error code. -*/ -int ima_must_measure(struct inode *inode, int mask, int function) -{ - int must_measure; - - must_measure = ima_match_policy(inode, function, mask); - return must_measure ? 0 : -EACCES; -} - -/* - * ima_collect_measurement - collect file measurement - * - * Calculate the file hash, if it doesn't already exist, - * storing the measurement and i_version in the iint. - * - * Must be called with iint->mutex held. - * - * Return 0 on success, error code otherwise - */ -int ima_collect_measurement(struct integrity_iint_cache *iint, - struct file *file) -{ - int result = -EEXIST; - - if (!(iint->flags & IMA_MEASURED)) { - u64 i_version = file->f_dentry->d_inode->i_version; - - memset(iint->digest, 0, IMA_DIGEST_SIZE); - result = ima_calc_hash(file, iint->digest); - if (!result) - iint->version = i_version; - } - return result; -} - -/* - * ima_store_measurement - store file measurement - * - * Create an "ima" template and then store the template by calling - * ima_store_template. - * - * We only get here if the inode has not already been measured, - * but the measurement could already exist: - * - multiple copies of the same file on either the same or - * different filesystems. - * - the inode was previously flushed as well as the iint info, - * containing the hashing info. - * - * Must be called with iint->mutex held. - */ -void ima_store_measurement(struct integrity_iint_cache *iint, - struct file *file, const unsigned char *filename) -{ - const char *op = "add_template_measure"; - const char *audit_cause = "ENOMEM"; - int result = -ENOMEM; - struct inode *inode = file->f_dentry->d_inode; - struct ima_template_entry *entry; - int violation = 0; - - entry = kmalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) { - integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, - op, audit_cause, result, 0); - return; - } - memset(&entry->template, 0, sizeof(entry->template)); - memcpy(entry->template.digest, iint->digest, IMA_DIGEST_SIZE); - strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX); - - result = ima_store_template(entry, violation, inode); - if (!result || result == -EEXIST) - iint->flags |= IMA_MEASURED; - if (result < 0) - kfree(entry); -} diff --git a/ANDROID_3.4.5/security/integrity/ima/ima_audit.c b/ANDROID_3.4.5/security/integrity/ima/ima_audit.c deleted file mode 100644 index 21e96bf1..00000000 --- a/ANDROID_3.4.5/security/integrity/ima/ima_audit.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2008 IBM Corporation - * Author: Mimi Zohar <zohar@us.ibm.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * File: integrity_audit.c - * Audit calls for the integrity subsystem - */ - -#include <linux/fs.h> -#include <linux/gfp.h> -#include <linux/audit.h> -#include "ima.h" - -static int ima_audit; - -#ifdef CONFIG_IMA_AUDIT - -/* ima_audit_setup - enable informational auditing messages */ -static int __init ima_audit_setup(char *str) -{ - unsigned long audit; - - if (!strict_strtoul(str, 0, &audit)) - ima_audit = audit ? 1 : 0; - return 1; -} -__setup("ima_audit=", ima_audit_setup); -#endif - -void integrity_audit_msg(int audit_msgno, struct inode *inode, - const unsigned char *fname, const char *op, - const char *cause, int result, int audit_info) -{ - struct audit_buffer *ab; - - if (!ima_audit && audit_info == 1) /* Skip informational messages */ - return; - - ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno); - audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u", - current->pid, current_cred()->uid, - audit_get_loginuid(current), - audit_get_sessionid(current)); - audit_log_task_context(ab); - audit_log_format(ab, " op="); - audit_log_string(ab, op); - audit_log_format(ab, " cause="); - audit_log_string(ab, cause); - audit_log_format(ab, " comm="); - audit_log_untrustedstring(ab, current->comm); - if (fname) { - audit_log_format(ab, " name="); - audit_log_untrustedstring(ab, fname); - } - if (inode) { - audit_log_format(ab, " dev="); - audit_log_untrustedstring(ab, inode->i_sb->s_id); - audit_log_format(ab, " ino=%lu", inode->i_ino); - } - audit_log_format(ab, " res=%d", !result); - audit_log_end(ab); -} diff --git a/ANDROID_3.4.5/security/integrity/ima/ima_crypto.c b/ANDROID_3.4.5/security/integrity/ima/ima_crypto.c deleted file mode 100644 index 9b3ade74..00000000 --- a/ANDROID_3.4.5/security/integrity/ima/ima_crypto.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2005,2006,2007,2008 IBM Corporation - * - * Authors: - * Mimi Zohar <zohar@us.ibm.com> - * Kylene Hall <kjhall@us.ibm.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * File: ima_crypto.c - * Calculates md5/sha1 file hash, template hash, boot-aggreate hash - */ - -#include <linux/kernel.h> -#include <linux/file.h> -#include <linux/crypto.h> -#include <linux/scatterlist.h> -#include <linux/err.h> -#include <linux/slab.h> -#include "ima.h" - -static int init_desc(struct hash_desc *desc) -{ - int rc; - - desc->tfm = crypto_alloc_hash(ima_hash, 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(desc->tfm)) { - pr_info("IMA: failed to load %s transform: %ld\n", - ima_hash, PTR_ERR(desc->tfm)); - rc = PTR_ERR(desc->tfm); - return rc; - } - desc->flags = 0; - rc = crypto_hash_init(desc); - if (rc) - crypto_free_hash(desc->tfm); - return rc; -} - -/* - * Calculate the MD5/SHA1 file digest - */ -int ima_calc_hash(struct file *file, char *digest) -{ - struct hash_desc desc; - struct scatterlist sg[1]; - loff_t i_size, offset = 0; - char *rbuf; - int rc; - - rc = init_desc(&desc); - if (rc != 0) - return rc; - - rbuf = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (!rbuf) { - rc = -ENOMEM; - goto out; - } - i_size = i_size_read(file->f_dentry->d_inode); - while (offset < i_size) { - int rbuf_len; - - rbuf_len = kernel_read(file, offset, rbuf, PAGE_SIZE); - if (rbuf_len < 0) { - rc = rbuf_len; - break; - } - if (rbuf_len == 0) - break; - offset += rbuf_len; - sg_init_one(sg, rbuf, rbuf_len); - - rc = crypto_hash_update(&desc, sg, rbuf_len); - if (rc) - break; - } - kfree(rbuf); - if (!rc) - rc = crypto_hash_final(&desc, digest); -out: - crypto_free_hash(desc.tfm); - return rc; -} - -/* - * Calculate the hash of a given template - */ -int ima_calc_template_hash(int template_len, void *template, char *digest) -{ - struct hash_desc desc; - struct scatterlist sg[1]; - int rc; - - rc = init_desc(&desc); - if (rc != 0) - return rc; - - sg_init_one(sg, template, template_len); - rc = crypto_hash_update(&desc, sg, template_len); - if (!rc) - rc = crypto_hash_final(&desc, digest); - crypto_free_hash(desc.tfm); - return rc; -} - -static void __init ima_pcrread(int idx, u8 *pcr) -{ - if (!ima_used_chip) - return; - - if (tpm_pcr_read(TPM_ANY_NUM, idx, pcr) != 0) - pr_err("IMA: Error Communicating to TPM chip\n"); -} - -/* - * Calculate the boot aggregate hash - */ -int __init ima_calc_boot_aggregate(char *digest) -{ - struct hash_desc desc; - struct scatterlist sg; - u8 pcr_i[IMA_DIGEST_SIZE]; - int rc, i; - - rc = init_desc(&desc); - if (rc != 0) - return rc; - - /* cumulative sha1 over tpm registers 0-7 */ - for (i = TPM_PCR0; i < TPM_PCR8; i++) { - ima_pcrread(i, pcr_i); - /* now accumulate with current aggregate */ - sg_init_one(&sg, pcr_i, IMA_DIGEST_SIZE); - rc = crypto_hash_update(&desc, &sg, IMA_DIGEST_SIZE); - } - if (!rc) - crypto_hash_final(&desc, digest); - crypto_free_hash(desc.tfm); - return rc; -} diff --git a/ANDROID_3.4.5/security/integrity/ima/ima_fs.c b/ANDROID_3.4.5/security/integrity/ima/ima_fs.c deleted file mode 100644 index e1aa2b48..00000000 --- a/ANDROID_3.4.5/security/integrity/ima/ima_fs.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (C) 2005,2006,2007,2008 IBM Corporation - * - * Authors: - * Kylene Hall <kjhall@us.ibm.com> - * Reiner Sailer <sailer@us.ibm.com> - * Mimi Zohar <zohar@us.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * File: ima_fs.c - * implemenents security file system for reporting - * current measurement list and IMA statistics - */ -#include <linux/fcntl.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/seq_file.h> -#include <linux/rculist.h> -#include <linux/rcupdate.h> -#include <linux/parser.h> - -#include "ima.h" - -static int valid_policy = 1; -#define TMPBUFLEN 12 -static ssize_t ima_show_htable_value(char __user *buf, size_t count, - loff_t *ppos, atomic_long_t *val) -{ - char tmpbuf[TMPBUFLEN]; - ssize_t len; - - len = scnprintf(tmpbuf, TMPBUFLEN, "%li\n", atomic_long_read(val)); - return simple_read_from_buffer(buf, count, ppos, tmpbuf, len); -} - -static ssize_t ima_show_htable_violations(struct file *filp, - char __user *buf, - size_t count, loff_t *ppos) -{ - return ima_show_htable_value(buf, count, ppos, &ima_htable.violations); -} - -static const struct file_operations ima_htable_violations_ops = { - .read = ima_show_htable_violations, - .llseek = generic_file_llseek, -}; - -static ssize_t ima_show_measurements_count(struct file *filp, - char __user *buf, - size_t count, loff_t *ppos) -{ - return ima_show_htable_value(buf, count, ppos, &ima_htable.len); - -} - -static const struct file_operations ima_measurements_count_ops = { - .read = ima_show_measurements_count, - .llseek = generic_file_llseek, -}; - -/* returns pointer to hlist_node */ -static void *ima_measurements_start(struct seq_file *m, loff_t *pos) -{ - loff_t l = *pos; - struct ima_queue_entry *qe; - - /* we need a lock since pos could point beyond last element */ - rcu_read_lock(); - list_for_each_entry_rcu(qe, &ima_measurements, later) { - if (!l--) { - rcu_read_unlock(); - return qe; - } - } - rcu_read_unlock(); - return NULL; -} - -static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos) -{ - struct ima_queue_entry *qe = v; - - /* lock protects when reading beyond last element - * against concurrent list-extension - */ - rcu_read_lock(); - qe = list_entry_rcu(qe->later.next, - struct ima_queue_entry, later); - rcu_read_unlock(); - (*pos)++; - - return (&qe->later == &ima_measurements) ? NULL : qe; -} - -static void ima_measurements_stop(struct seq_file *m, void *v) -{ -} - -static void ima_putc(struct seq_file *m, void *data, int datalen) -{ - while (datalen--) - seq_putc(m, *(char *)data++); -} - -/* print format: - * 32bit-le=pcr# - * char[20]=template digest - * 32bit-le=template name size - * char[n]=template name - * eventdata[n]=template specific data - */ -static int ima_measurements_show(struct seq_file *m, void *v) -{ - /* the list never shrinks, so we don't need a lock here */ - struct ima_queue_entry *qe = v; - struct ima_template_entry *e; - int namelen; - u32 pcr = CONFIG_IMA_MEASURE_PCR_IDX; - - /* get entry */ - e = qe->entry; - if (e == NULL) - return -1; - - /* - * 1st: PCRIndex - * PCR used is always the same (config option) in - * little-endian format - */ - ima_putc(m, &pcr, sizeof pcr); - - /* 2nd: template digest */ - ima_putc(m, e->digest, IMA_DIGEST_SIZE); - - /* 3rd: template name size */ - namelen = strlen(e->template_name); - ima_putc(m, &namelen, sizeof namelen); - - /* 4th: template name */ - ima_putc(m, (void *)e->template_name, namelen); - - /* 5th: template specific data */ - ima_template_show(m, (struct ima_template_data *)&e->template, - IMA_SHOW_BINARY); - return 0; -} - -static const struct seq_operations ima_measurments_seqops = { - .start = ima_measurements_start, - .next = ima_measurements_next, - .stop = ima_measurements_stop, - .show = ima_measurements_show -}; - -static int ima_measurements_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &ima_measurments_seqops); -} - -static const struct file_operations ima_measurements_ops = { - .open = ima_measurements_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static void ima_print_digest(struct seq_file *m, u8 *digest) -{ - int i; - - for (i = 0; i < IMA_DIGEST_SIZE; i++) - seq_printf(m, "%02x", *(digest + i)); -} - -void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show) -{ - struct ima_template_data *entry = e; - int namelen; - - switch (show) { - case IMA_SHOW_ASCII: - ima_print_digest(m, entry->digest); - seq_printf(m, " %s\n", entry->file_name); - break; - case IMA_SHOW_BINARY: - ima_putc(m, entry->digest, IMA_DIGEST_SIZE); - - namelen = strlen(entry->file_name); - ima_putc(m, &namelen, sizeof namelen); - ima_putc(m, entry->file_name, namelen); - default: - break; - } -} - -/* print in ascii */ -static int ima_ascii_measurements_show(struct seq_file *m, void *v) -{ - /* the list never shrinks, so we don't need a lock here */ - struct ima_queue_entry *qe = v; - struct ima_template_entry *e; - - /* get entry */ - e = qe->entry; - if (e == NULL) - return -1; - - /* 1st: PCR used (config option) */ - seq_printf(m, "%2d ", CONFIG_IMA_MEASURE_PCR_IDX); - - /* 2nd: SHA1 template hash */ - ima_print_digest(m, e->digest); - - /* 3th: template name */ - seq_printf(m, " %s ", e->template_name); - - /* 4th: template specific data */ - ima_template_show(m, (struct ima_template_data *)&e->template, - IMA_SHOW_ASCII); - return 0; -} - -static const struct seq_operations ima_ascii_measurements_seqops = { - .start = ima_measurements_start, - .next = ima_measurements_next, - .stop = ima_measurements_stop, - .show = ima_ascii_measurements_show -}; - -static int ima_ascii_measurements_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &ima_ascii_measurements_seqops); -} - -static const struct file_operations ima_ascii_measurements_ops = { - .open = ima_ascii_measurements_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static ssize_t ima_write_policy(struct file *file, const char __user *buf, - size_t datalen, loff_t *ppos) -{ - char *data = NULL; - ssize_t result; - - if (datalen >= PAGE_SIZE) - datalen = PAGE_SIZE - 1; - - /* No partial writes. */ - result = -EINVAL; - if (*ppos != 0) - goto out; - - result = -ENOMEM; - data = kmalloc(datalen + 1, GFP_KERNEL); - if (!data) - goto out; - - *(data + datalen) = '\0'; - - result = -EFAULT; - if (copy_from_user(data, buf, datalen)) - goto out; - - result = ima_parse_add_rule(data); -out: - if (result < 0) - valid_policy = 0; - kfree(data); - return result; -} - -static struct dentry *ima_dir; -static struct dentry *binary_runtime_measurements; -static struct dentry *ascii_runtime_measurements; -static struct dentry *runtime_measurements_count; -static struct dentry *violations; -static struct dentry *ima_policy; - -static atomic_t policy_opencount = ATOMIC_INIT(1); -/* - * ima_open_policy: sequentialize access to the policy file - */ -static int ima_open_policy(struct inode * inode, struct file * filp) -{ - /* No point in being allowed to open it if you aren't going to write */ - if (!(filp->f_flags & O_WRONLY)) - return -EACCES; - if (atomic_dec_and_test(&policy_opencount)) - return 0; - return -EBUSY; -} - -/* - * ima_release_policy - start using the new measure policy rules. - * - * Initially, ima_measure points to the default policy rules, now - * point to the new policy rules, and remove the securityfs policy file, - * assuming a valid policy. - */ -static int ima_release_policy(struct inode *inode, struct file *file) -{ - if (!valid_policy) { - ima_delete_rules(); - valid_policy = 1; - atomic_set(&policy_opencount, 1); - return 0; - } - ima_update_policy(); - securityfs_remove(ima_policy); - ima_policy = NULL; - return 0; -} - -static const struct file_operations ima_measure_policy_ops = { - .open = ima_open_policy, - .write = ima_write_policy, - .release = ima_release_policy, - .llseek = generic_file_llseek, -}; - -int __init ima_fs_init(void) -{ - ima_dir = securityfs_create_dir("ima", NULL); - if (IS_ERR(ima_dir)) - return -1; - - binary_runtime_measurements = - securityfs_create_file("binary_runtime_measurements", - S_IRUSR | S_IRGRP, ima_dir, NULL, - &ima_measurements_ops); - if (IS_ERR(binary_runtime_measurements)) - goto out; - - ascii_runtime_measurements = - securityfs_create_file("ascii_runtime_measurements", - S_IRUSR | S_IRGRP, ima_dir, NULL, - &ima_ascii_measurements_ops); - if (IS_ERR(ascii_runtime_measurements)) - goto out; - - runtime_measurements_count = - securityfs_create_file("runtime_measurements_count", - S_IRUSR | S_IRGRP, ima_dir, NULL, - &ima_measurements_count_ops); - if (IS_ERR(runtime_measurements_count)) - goto out; - - violations = - securityfs_create_file("violations", S_IRUSR | S_IRGRP, - ima_dir, NULL, &ima_htable_violations_ops); - if (IS_ERR(violations)) - goto out; - - ima_policy = securityfs_create_file("policy", - S_IWUSR, - ima_dir, NULL, - &ima_measure_policy_ops); - if (IS_ERR(ima_policy)) - goto out; - - return 0; -out: - securityfs_remove(runtime_measurements_count); - securityfs_remove(ascii_runtime_measurements); - securityfs_remove(binary_runtime_measurements); - securityfs_remove(ima_dir); - securityfs_remove(ima_policy); - return -1; -} - -void __exit ima_fs_cleanup(void) -{ - securityfs_remove(violations); - securityfs_remove(runtime_measurements_count); - securityfs_remove(ascii_runtime_measurements); - securityfs_remove(binary_runtime_measurements); - securityfs_remove(ima_dir); - securityfs_remove(ima_policy); -} diff --git a/ANDROID_3.4.5/security/integrity/ima/ima_init.c b/ANDROID_3.4.5/security/integrity/ima/ima_init.c deleted file mode 100644 index 17f1f060..00000000 --- a/ANDROID_3.4.5/security/integrity/ima/ima_init.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2005,2006,2007,2008 IBM Corporation - * - * Authors: - * Reiner Sailer <sailer@watson.ibm.com> - * Leendert van Doorn <leendert@watson.ibm.com> - * Mimi Zohar <zohar@us.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * File: ima_init.c - * initialization and cleanup functions - */ -#include <linux/module.h> -#include <linux/scatterlist.h> -#include <linux/slab.h> -#include <linux/err.h> -#include "ima.h" - -/* name for boot aggregate entry */ -static const char *boot_aggregate_name = "boot_aggregate"; -int ima_used_chip; - -/* Add the boot aggregate to the IMA measurement list and extend - * the PCR register. - * - * Calculate the boot aggregate, a SHA1 over tpm registers 0-7, - * assuming a TPM chip exists, and zeroes if the TPM chip does not - * exist. Add the boot aggregate measurement to the measurement - * list and extend the PCR register. - * - * If a tpm chip does not exist, indicate the core root of trust is - * not hardware based by invalidating the aggregate PCR value. - * (The aggregate PCR value is invalidated by adding one value to - * the measurement list and extending the aggregate PCR value with - * a different value.) Violations add a zero entry to the measurement - * list and extend the aggregate PCR value with ff...ff's. - */ -static void __init ima_add_boot_aggregate(void) -{ - struct ima_template_entry *entry; - const char *op = "add_boot_aggregate"; - const char *audit_cause = "ENOMEM"; - int result = -ENOMEM; - int violation = 1; - - entry = kmalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - goto err_out; - - memset(&entry->template, 0, sizeof(entry->template)); - strncpy(entry->template.file_name, boot_aggregate_name, - IMA_EVENT_NAME_LEN_MAX); - if (ima_used_chip) { - violation = 0; - result = ima_calc_boot_aggregate(entry->template.digest); - if (result < 0) { - audit_cause = "hashing_error"; - kfree(entry); - goto err_out; - } - } - result = ima_store_template(entry, violation, NULL); - if (result < 0) - kfree(entry); - return; -err_out: - integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op, - audit_cause, result, 0); -} - -int __init ima_init(void) -{ - u8 pcr_i[IMA_DIGEST_SIZE]; - int rc; - - ima_used_chip = 0; - rc = tpm_pcr_read(TPM_ANY_NUM, 0, pcr_i); - if (rc == 0) - ima_used_chip = 1; - - if (!ima_used_chip) - pr_info("IMA: No TPM chip found, activating TPM-bypass!\n"); - - ima_add_boot_aggregate(); /* boot aggregate must be first entry */ - ima_init_policy(); - - return ima_fs_init(); -} - -void __exit ima_cleanup(void) -{ - ima_fs_cleanup(); -} diff --git a/ANDROID_3.4.5/security/integrity/ima/ima_main.c b/ANDROID_3.4.5/security/integrity/ima/ima_main.c deleted file mode 100644 index 1eff5cb0..00000000 --- a/ANDROID_3.4.5/security/integrity/ima/ima_main.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 2005,2006,2007,2008 IBM Corporation - * - * Authors: - * Reiner Sailer <sailer@watson.ibm.com> - * Serge Hallyn <serue@us.ibm.com> - * Kylene Hall <kylene@us.ibm.com> - * Mimi Zohar <zohar@us.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * File: ima_main.c - * implements the IMA hooks: ima_bprm_check, ima_file_mmap, - * and ima_file_check. - */ -#include <linux/module.h> -#include <linux/file.h> -#include <linux/binfmts.h> -#include <linux/mount.h> -#include <linux/mman.h> -#include <linux/slab.h> -#include <linux/ima.h> - -#include "ima.h" - -int ima_initialized; - -char *ima_hash = "sha1"; -static int __init hash_setup(char *str) -{ - if (strncmp(str, "md5", 3) == 0) - ima_hash = "md5"; - return 1; -} -__setup("ima_hash=", hash_setup); - -/* - * ima_rdwr_violation_check - * - * Only invalidate the PCR for measured files: - * - Opening a file for write when already open for read, - * results in a time of measure, time of use (ToMToU) error. - * - Opening a file for read when already open for write, - * could result in a file measurement error. - * - */ -static void ima_rdwr_violation_check(struct file *file) -{ - struct dentry *dentry = file->f_path.dentry; - struct inode *inode = dentry->d_inode; - fmode_t mode = file->f_mode; - int rc; - bool send_tomtou = false, send_writers = false; - - if (!S_ISREG(inode->i_mode) || !ima_initialized) - return; - - mutex_lock(&inode->i_mutex); /* file metadata: permissions, xattr */ - - if (mode & FMODE_WRITE) { - if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) - send_tomtou = true; - goto out; - } - - rc = ima_must_measure(inode, MAY_READ, FILE_CHECK); - if (rc < 0) - goto out; - - if (atomic_read(&inode->i_writecount) > 0) - send_writers = true; -out: - mutex_unlock(&inode->i_mutex); - - if (send_tomtou) - ima_add_violation(inode, dentry->d_name.name, "invalid_pcr", - "ToMToU"); - if (send_writers) - ima_add_violation(inode, dentry->d_name.name, "invalid_pcr", - "open_writers"); -} - -static void ima_check_last_writer(struct integrity_iint_cache *iint, - struct inode *inode, - struct file *file) -{ - fmode_t mode = file->f_mode; - - mutex_lock(&iint->mutex); - if (mode & FMODE_WRITE && - atomic_read(&inode->i_writecount) == 1 && - iint->version != inode->i_version) - iint->flags &= ~IMA_MEASURED; - mutex_unlock(&iint->mutex); -} - -/** - * ima_file_free - called on __fput() - * @file: pointer to file structure being freed - * - * Flag files that changed, based on i_version - */ -void ima_file_free(struct file *file) -{ - struct inode *inode = file->f_dentry->d_inode; - struct integrity_iint_cache *iint; - - if (!iint_initialized || !S_ISREG(inode->i_mode)) - return; - - iint = integrity_iint_find(inode); - if (!iint) - return; - - ima_check_last_writer(iint, inode, file); -} - -static int process_measurement(struct file *file, const unsigned char *filename, - int mask, int function) -{ - struct inode *inode = file->f_dentry->d_inode; - struct integrity_iint_cache *iint; - int rc = 0; - - if (!ima_initialized || !S_ISREG(inode->i_mode)) - return 0; - - rc = ima_must_measure(inode, mask, function); - if (rc != 0) - return rc; -retry: - iint = integrity_iint_find(inode); - if (!iint) { - rc = integrity_inode_alloc(inode); - if (!rc || rc == -EEXIST) - goto retry; - return rc; - } - - mutex_lock(&iint->mutex); - - rc = iint->flags & IMA_MEASURED ? 1 : 0; - if (rc != 0) - goto out; - - rc = ima_collect_measurement(iint, file); - if (!rc) - ima_store_measurement(iint, file, filename); -out: - mutex_unlock(&iint->mutex); - return rc; -} - -/** - * ima_file_mmap - based on policy, collect/store measurement. - * @file: pointer to the file to be measured (May be NULL) - * @prot: contains the protection that will be applied by the kernel. - * - * Measure files being mmapped executable based on the ima_must_measure() - * policy decision. - * - * Return 0 on success, an error code on failure. - * (Based on the results of appraise_measurement().) - */ -int ima_file_mmap(struct file *file, unsigned long prot) -{ - int rc; - - if (!file) - return 0; - if (prot & PROT_EXEC) - rc = process_measurement(file, file->f_dentry->d_name.name, - MAY_EXEC, FILE_MMAP); - return 0; -} - -/** - * ima_bprm_check - based on policy, collect/store measurement. - * @bprm: contains the linux_binprm structure - * - * The OS protects against an executable file, already open for write, - * from being executed in deny_write_access() and an executable file, - * already open for execute, from being modified in get_write_access(). - * So we can be certain that what we verify and measure here is actually - * what is being executed. - * - * Return 0 on success, an error code on failure. - * (Based on the results of appraise_measurement().) - */ -int ima_bprm_check(struct linux_binprm *bprm) -{ - int rc; - - rc = process_measurement(bprm->file, bprm->filename, - MAY_EXEC, BPRM_CHECK); - return 0; -} - -/** - * ima_path_check - based on policy, collect/store measurement. - * @file: pointer to the file to be measured - * @mask: contains MAY_READ, MAY_WRITE or MAY_EXECUTE - * - * Measure files based on the ima_must_measure() policy decision. - * - * Always return 0 and audit dentry_open failures. - * (Return code will be based upon measurement appraisal.) - */ -int ima_file_check(struct file *file, int mask) -{ - int rc; - - ima_rdwr_violation_check(file); - rc = process_measurement(file, file->f_dentry->d_name.name, - mask & (MAY_READ | MAY_WRITE | MAY_EXEC), - FILE_CHECK); - return 0; -} -EXPORT_SYMBOL_GPL(ima_file_check); - -static int __init init_ima(void) -{ - int error; - - error = ima_init(); - ima_initialized = 1; - return error; -} - -static void __exit cleanup_ima(void) -{ - ima_cleanup(); -} - -late_initcall(init_ima); /* Start IMA after the TPM is available */ - -MODULE_DESCRIPTION("Integrity Measurement Architecture"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/security/integrity/ima/ima_policy.c b/ANDROID_3.4.5/security/integrity/ima/ima_policy.c deleted file mode 100644 index d8edff20..00000000 --- a/ANDROID_3.4.5/security/integrity/ima/ima_policy.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright (C) 2008 IBM Corporation - * Author: Mimi Zohar <zohar@us.ibm.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * ima_policy.c - * - initialize default measure policy rules - * - */ -#include <linux/module.h> -#include <linux/list.h> -#include <linux/security.h> -#include <linux/magic.h> -#include <linux/parser.h> -#include <linux/slab.h> - -#include "ima.h" - -/* flags definitions */ -#define IMA_FUNC 0x0001 -#define IMA_MASK 0x0002 -#define IMA_FSMAGIC 0x0004 -#define IMA_UID 0x0008 - -enum ima_action { UNKNOWN = -1, DONT_MEASURE = 0, MEASURE }; - -#define MAX_LSM_RULES 6 -enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, - LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE -}; - -struct ima_measure_rule_entry { - struct list_head list; - enum ima_action action; - unsigned int flags; - enum ima_hooks func; - int mask; - unsigned long fsmagic; - uid_t uid; - struct { - void *rule; /* LSM file metadata specific */ - int type; /* audit type */ - } lsm[MAX_LSM_RULES]; -}; - -/* - * Without LSM specific knowledge, the default policy can only be - * written in terms of .action, .func, .mask, .fsmagic, and .uid - */ - -/* - * The minimum rule set to allow for full TCB coverage. Measures all files - * opened or mmap for exec and everything read by root. Dangerous because - * normal users can easily run the machine out of memory simply building - * and running executables. - */ -static struct ima_measure_rule_entry default_rules[] = { - {.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC}, - {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, - {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, - {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, - {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC}, - {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC}, - {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC}, - {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC, - .flags = IMA_FUNC | IMA_MASK}, - {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC, - .flags = IMA_FUNC | IMA_MASK}, - {.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = 0, - .flags = IMA_FUNC | IMA_MASK | IMA_UID}, -}; - -static LIST_HEAD(measure_default_rules); -static LIST_HEAD(measure_policy_rules); -static struct list_head *ima_measure; - -static DEFINE_MUTEX(ima_measure_mutex); - -static bool ima_use_tcb __initdata; -static int __init default_policy_setup(char *str) -{ - ima_use_tcb = 1; - return 1; -} -__setup("ima_tcb", default_policy_setup); - -/** - * ima_match_rules - determine whether an inode matches the measure rule. - * @rule: a pointer to a rule - * @inode: a pointer to an inode - * @func: LIM hook identifier - * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) - * - * Returns true on rule match, false on failure. - */ -static bool ima_match_rules(struct ima_measure_rule_entry *rule, - struct inode *inode, enum ima_hooks func, int mask) -{ - struct task_struct *tsk = current; - const struct cred *cred = current_cred(); - int i; - - if ((rule->flags & IMA_FUNC) && rule->func != func) - return false; - if ((rule->flags & IMA_MASK) && rule->mask != mask) - return false; - if ((rule->flags & IMA_FSMAGIC) - && rule->fsmagic != inode->i_sb->s_magic) - return false; - if ((rule->flags & IMA_UID) && rule->uid != cred->uid) - return false; - for (i = 0; i < MAX_LSM_RULES; i++) { - int rc = 0; - u32 osid, sid; - - if (!rule->lsm[i].rule) - continue; - - switch (i) { - case LSM_OBJ_USER: - case LSM_OBJ_ROLE: - case LSM_OBJ_TYPE: - security_inode_getsecid(inode, &osid); - rc = security_filter_rule_match(osid, - rule->lsm[i].type, - Audit_equal, - rule->lsm[i].rule, - NULL); - break; - case LSM_SUBJ_USER: - case LSM_SUBJ_ROLE: - case LSM_SUBJ_TYPE: - security_task_getsecid(tsk, &sid); - rc = security_filter_rule_match(sid, - rule->lsm[i].type, - Audit_equal, - rule->lsm[i].rule, - NULL); - default: - break; - } - if (!rc) - return false; - } - return true; -} - -/** - * ima_match_policy - decision based on LSM and other conditions - * @inode: pointer to an inode for which the policy decision is being made - * @func: IMA hook identifier - * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) - * - * Measure decision based on func/mask/fsmagic and LSM(subj/obj/type) - * conditions. - * - * (There is no need for locking when walking the policy list, - * as elements in the list are never deleted, nor does the list - * change.) - */ -int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask) -{ - struct ima_measure_rule_entry *entry; - - list_for_each_entry(entry, ima_measure, list) { - bool rc; - - rc = ima_match_rules(entry, inode, func, mask); - if (rc) - return entry->action; - } - return 0; -} - -/** - * ima_init_policy - initialize the default measure rules. - * - * ima_measure points to either the measure_default_rules or the - * the new measure_policy_rules. - */ -void __init ima_init_policy(void) -{ - int i, entries; - - /* if !ima_use_tcb set entries = 0 so we load NO default rules */ - if (ima_use_tcb) - entries = ARRAY_SIZE(default_rules); - else - entries = 0; - - for (i = 0; i < entries; i++) - list_add_tail(&default_rules[i].list, &measure_default_rules); - ima_measure = &measure_default_rules; -} - -/** - * ima_update_policy - update default_rules with new measure rules - * - * Called on file .release to update the default rules with a complete new - * policy. Once updated, the policy is locked, no additional rules can be - * added to the policy. - */ -void ima_update_policy(void) -{ - const char *op = "policy_update"; - const char *cause = "already exists"; - int result = 1; - int audit_info = 0; - - if (ima_measure == &measure_default_rules) { - ima_measure = &measure_policy_rules; - cause = "complete"; - result = 0; - } - integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, - NULL, op, cause, result, audit_info); -} - -enum { - Opt_err = -1, - Opt_measure = 1, Opt_dont_measure, - Opt_obj_user, Opt_obj_role, Opt_obj_type, - Opt_subj_user, Opt_subj_role, Opt_subj_type, - Opt_func, Opt_mask, Opt_fsmagic, Opt_uid -}; - -static match_table_t policy_tokens = { - {Opt_measure, "measure"}, - {Opt_dont_measure, "dont_measure"}, - {Opt_obj_user, "obj_user=%s"}, - {Opt_obj_role, "obj_role=%s"}, - {Opt_obj_type, "obj_type=%s"}, - {Opt_subj_user, "subj_user=%s"}, - {Opt_subj_role, "subj_role=%s"}, - {Opt_subj_type, "subj_type=%s"}, - {Opt_func, "func=%s"}, - {Opt_mask, "mask=%s"}, - {Opt_fsmagic, "fsmagic=%s"}, - {Opt_uid, "uid=%s"}, - {Opt_err, NULL} -}; - -static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry, - char *args, int lsm_rule, int audit_type) -{ - int result; - - if (entry->lsm[lsm_rule].rule) - return -EINVAL; - - entry->lsm[lsm_rule].type = audit_type; - result = security_filter_rule_init(entry->lsm[lsm_rule].type, - Audit_equal, args, - &entry->lsm[lsm_rule].rule); - if (!entry->lsm[lsm_rule].rule) - return -EINVAL; - return result; -} - -static void ima_log_string(struct audit_buffer *ab, char *key, char *value) -{ - audit_log_format(ab, "%s=", key); - audit_log_untrustedstring(ab, value); - audit_log_format(ab, " "); -} - -static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) -{ - struct audit_buffer *ab; - char *p; - int result = 0; - - ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE); - - entry->uid = -1; - entry->action = UNKNOWN; - while ((p = strsep(&rule, " \t")) != NULL) { - substring_t args[MAX_OPT_ARGS]; - int token; - unsigned long lnum; - - if (result < 0) - break; - if ((*p == '\0') || (*p == ' ') || (*p == '\t')) - continue; - token = match_token(p, policy_tokens, args); - switch (token) { - case Opt_measure: - ima_log_string(ab, "action", "measure"); - - if (entry->action != UNKNOWN) - result = -EINVAL; - - entry->action = MEASURE; - break; - case Opt_dont_measure: - ima_log_string(ab, "action", "dont_measure"); - - if (entry->action != UNKNOWN) - result = -EINVAL; - - entry->action = DONT_MEASURE; - break; - case Opt_func: - ima_log_string(ab, "func", args[0].from); - - if (entry->func) - result = -EINVAL; - - if (strcmp(args[0].from, "FILE_CHECK") == 0) - entry->func = FILE_CHECK; - /* PATH_CHECK is for backwards compat */ - else if (strcmp(args[0].from, "PATH_CHECK") == 0) - entry->func = FILE_CHECK; - else if (strcmp(args[0].from, "FILE_MMAP") == 0) - entry->func = FILE_MMAP; - else if (strcmp(args[0].from, "BPRM_CHECK") == 0) - entry->func = BPRM_CHECK; - else - result = -EINVAL; - if (!result) - entry->flags |= IMA_FUNC; - break; - case Opt_mask: - ima_log_string(ab, "mask", args[0].from); - - if (entry->mask) - result = -EINVAL; - - if ((strcmp(args[0].from, "MAY_EXEC")) == 0) - entry->mask = MAY_EXEC; - else if (strcmp(args[0].from, "MAY_WRITE") == 0) - entry->mask = MAY_WRITE; - else if (strcmp(args[0].from, "MAY_READ") == 0) - entry->mask = MAY_READ; - else if (strcmp(args[0].from, "MAY_APPEND") == 0) - entry->mask = MAY_APPEND; - else - result = -EINVAL; - if (!result) - entry->flags |= IMA_MASK; - break; - case Opt_fsmagic: - ima_log_string(ab, "fsmagic", args[0].from); - - if (entry->fsmagic) { - result = -EINVAL; - break; - } - - result = strict_strtoul(args[0].from, 16, - &entry->fsmagic); - if (!result) - entry->flags |= IMA_FSMAGIC; - break; - case Opt_uid: - ima_log_string(ab, "uid", args[0].from); - - if (entry->uid != -1) { - result = -EINVAL; - break; - } - - result = strict_strtoul(args[0].from, 10, &lnum); - if (!result) { - entry->uid = (uid_t) lnum; - if (entry->uid != lnum) - result = -EINVAL; - else - entry->flags |= IMA_UID; - } - break; - case Opt_obj_user: - ima_log_string(ab, "obj_user", args[0].from); - result = ima_lsm_rule_init(entry, args[0].from, - LSM_OBJ_USER, - AUDIT_OBJ_USER); - break; - case Opt_obj_role: - ima_log_string(ab, "obj_role", args[0].from); - result = ima_lsm_rule_init(entry, args[0].from, - LSM_OBJ_ROLE, - AUDIT_OBJ_ROLE); - break; - case Opt_obj_type: - ima_log_string(ab, "obj_type", args[0].from); - result = ima_lsm_rule_init(entry, args[0].from, - LSM_OBJ_TYPE, - AUDIT_OBJ_TYPE); - break; - case Opt_subj_user: - ima_log_string(ab, "subj_user", args[0].from); - result = ima_lsm_rule_init(entry, args[0].from, - LSM_SUBJ_USER, - AUDIT_SUBJ_USER); - break; - case Opt_subj_role: - ima_log_string(ab, "subj_role", args[0].from); - result = ima_lsm_rule_init(entry, args[0].from, - LSM_SUBJ_ROLE, - AUDIT_SUBJ_ROLE); - break; - case Opt_subj_type: - ima_log_string(ab, "subj_type", args[0].from); - result = ima_lsm_rule_init(entry, args[0].from, - LSM_SUBJ_TYPE, - AUDIT_SUBJ_TYPE); - break; - case Opt_err: - ima_log_string(ab, "UNKNOWN", p); - result = -EINVAL; - break; - } - } - if (!result && (entry->action == UNKNOWN)) - result = -EINVAL; - - audit_log_format(ab, "res=%d", !result); - audit_log_end(ab); - return result; -} - -/** - * ima_parse_add_rule - add a rule to measure_policy_rules - * @rule - ima measurement policy rule - * - * Uses a mutex to protect the policy list from multiple concurrent writers. - * Returns the length of the rule parsed, an error code on failure - */ -ssize_t ima_parse_add_rule(char *rule) -{ - const char *op = "update_policy"; - char *p; - struct ima_measure_rule_entry *entry; - ssize_t result, len; - int audit_info = 0; - - /* Prevent installed policy from changing */ - if (ima_measure != &measure_default_rules) { - integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, - NULL, op, "already exists", - -EACCES, audit_info); - return -EACCES; - } - - entry = kzalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) { - integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, - NULL, op, "-ENOMEM", -ENOMEM, audit_info); - return -ENOMEM; - } - - INIT_LIST_HEAD(&entry->list); - - p = strsep(&rule, "\n"); - len = strlen(p) + 1; - - if (*p == '#') { - kfree(entry); - return len; - } - - result = ima_parse_rule(p, entry); - if (result) { - kfree(entry); - integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, - NULL, op, "invalid policy", result, - audit_info); - return result; - } - - mutex_lock(&ima_measure_mutex); - list_add_tail(&entry->list, &measure_policy_rules); - mutex_unlock(&ima_measure_mutex); - - return len; -} - -/* ima_delete_rules called to cleanup invalid policy */ -void ima_delete_rules(void) -{ - struct ima_measure_rule_entry *entry, *tmp; - - mutex_lock(&ima_measure_mutex); - list_for_each_entry_safe(entry, tmp, &measure_policy_rules, list) { - list_del(&entry->list); - kfree(entry); - } - mutex_unlock(&ima_measure_mutex); -} diff --git a/ANDROID_3.4.5/security/integrity/ima/ima_queue.c b/ANDROID_3.4.5/security/integrity/ima/ima_queue.c deleted file mode 100644 index 55a6271b..00000000 --- a/ANDROID_3.4.5/security/integrity/ima/ima_queue.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2005,2006,2007,2008 IBM Corporation - * - * Authors: - * Serge Hallyn <serue@us.ibm.com> - * Reiner Sailer <sailer@watson.ibm.com> - * Mimi Zohar <zohar@us.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * File: ima_queue.c - * Implements queues that store template measurements and - * maintains aggregate over the stored measurements - * in the pre-configured TPM PCR (if available). - * The measurement list is append-only. No entry is - * ever removed or changed during the boot-cycle. - */ -#include <linux/module.h> -#include <linux/rculist.h> -#include <linux/slab.h> -#include "ima.h" - -#define AUDIT_CAUSE_LEN_MAX 32 - -LIST_HEAD(ima_measurements); /* list of all measurements */ - -/* key: inode (before secure-hashing a file) */ -struct ima_h_table ima_htable = { - .len = ATOMIC_LONG_INIT(0), - .violations = ATOMIC_LONG_INIT(0), - .queue[0 ... IMA_MEASURE_HTABLE_SIZE - 1] = HLIST_HEAD_INIT -}; - -/* mutex protects atomicity of extending measurement list - * and extending the TPM PCR aggregate. Since tpm_extend can take - * long (and the tpm driver uses a mutex), we can't use the spinlock. - */ -static DEFINE_MUTEX(ima_extend_list_mutex); - -/* lookup up the digest value in the hash table, and return the entry */ -static struct ima_queue_entry *ima_lookup_digest_entry(u8 *digest_value) -{ - struct ima_queue_entry *qe, *ret = NULL; - unsigned int key; - struct hlist_node *pos; - int rc; - - key = ima_hash_key(digest_value); - rcu_read_lock(); - hlist_for_each_entry_rcu(qe, pos, &ima_htable.queue[key], hnext) { - rc = memcmp(qe->entry->digest, digest_value, IMA_DIGEST_SIZE); - if (rc == 0) { - ret = qe; - break; - } - } - rcu_read_unlock(); - return ret; -} - -/* ima_add_template_entry helper function: - * - Add template entry to measurement list and hash table. - * - * (Called with ima_extend_list_mutex held.) - */ -static int ima_add_digest_entry(struct ima_template_entry *entry) -{ - struct ima_queue_entry *qe; - unsigned int key; - - qe = kmalloc(sizeof(*qe), GFP_KERNEL); - if (qe == NULL) { - pr_err("IMA: OUT OF MEMORY ERROR creating queue entry.\n"); - return -ENOMEM; - } - qe->entry = entry; - - INIT_LIST_HEAD(&qe->later); - list_add_tail_rcu(&qe->later, &ima_measurements); - - atomic_long_inc(&ima_htable.len); - key = ima_hash_key(entry->digest); - hlist_add_head_rcu(&qe->hnext, &ima_htable.queue[key]); - return 0; -} - -static int ima_pcr_extend(const u8 *hash) -{ - int result = 0; - - if (!ima_used_chip) - return result; - - result = tpm_pcr_extend(TPM_ANY_NUM, CONFIG_IMA_MEASURE_PCR_IDX, hash); - if (result != 0) - pr_err("IMA: Error Communicating to TPM chip, result: %d\n", - result); - return result; -} - -/* Add template entry to the measurement list and hash table, - * and extend the pcr. - */ -int ima_add_template_entry(struct ima_template_entry *entry, int violation, - const char *op, struct inode *inode) -{ - u8 digest[IMA_DIGEST_SIZE]; - const char *audit_cause = "hash_added"; - char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX]; - int audit_info = 1; - int result = 0, tpmresult = 0; - - mutex_lock(&ima_extend_list_mutex); - if (!violation) { - memcpy(digest, entry->digest, sizeof digest); - if (ima_lookup_digest_entry(digest)) { - audit_cause = "hash_exists"; - result = -EEXIST; - goto out; - } - } - - result = ima_add_digest_entry(entry); - if (result < 0) { - audit_cause = "ENOMEM"; - audit_info = 0; - goto out; - } - - if (violation) /* invalidate pcr */ - memset(digest, 0xff, sizeof digest); - - tpmresult = ima_pcr_extend(digest); - if (tpmresult != 0) { - snprintf(tpm_audit_cause, AUDIT_CAUSE_LEN_MAX, "TPM_error(%d)", - tpmresult); - audit_cause = tpm_audit_cause; - audit_info = 0; - } -out: - mutex_unlock(&ima_extend_list_mutex); - integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, - entry->template.file_name, - op, audit_cause, result, audit_info); - return result; -} diff --git a/ANDROID_3.4.5/security/integrity/integrity.h b/ANDROID_3.4.5/security/integrity/integrity.h deleted file mode 100644 index 7a25ecec..00000000 --- a/ANDROID_3.4.5/security/integrity/integrity.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2009-2010 IBM Corporation - * - * Authors: - * Mimi Zohar <zohar@us.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - */ - -#include <linux/types.h> -#include <linux/integrity.h> -#include <crypto/sha.h> - -/* iint cache flags */ -#define IMA_MEASURED 0x01 - -enum evm_ima_xattr_type { - IMA_XATTR_DIGEST = 0x01, - EVM_XATTR_HMAC, - EVM_IMA_XATTR_DIGSIG, -}; - -struct evm_ima_xattr_data { - u8 type; - u8 digest[SHA1_DIGEST_SIZE]; -} __attribute__((packed)); - -/* integrity data associated with an inode */ -struct integrity_iint_cache { - struct rb_node rb_node; /* rooted in integrity_iint_tree */ - struct inode *inode; /* back pointer to inode in question */ - u64 version; /* track inode changes */ - unsigned char flags; - u8 digest[SHA1_DIGEST_SIZE]; - struct mutex mutex; /* protects: version, flags, digest */ - enum integrity_status evm_status; -}; - -/* 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); - -#define INTEGRITY_KEYRING_EVM 0 -#define INTEGRITY_KEYRING_MODULE 1 -#define INTEGRITY_KEYRING_IMA 2 -#define INTEGRITY_KEYRING_MAX 3 - -#ifdef CONFIG_INTEGRITY_SIGNATURE - -int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, - const char *digest, int digestlen); - -#else - -static inline int integrity_digsig_verify(const unsigned int id, - const char *sig, int siglen, - const char *digest, int digestlen) -{ - return -EOPNOTSUPP; -} - -#endif /* CONFIG_INTEGRITY_SIGNATURE */ - -/* set during initialization */ -extern int iint_initialized; |