summaryrefslogtreecommitdiff
path: root/security/integrity
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
committerScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
commit62b8c978ee6b8d135d9e7953221de58000dba986 (patch)
tree683b04b2e627f6710c22c151b23c8cc9a165315e /security/integrity
parent78fd82238d0e5716578c326404184a27ba67fd6e (diff)
downloadlinux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'security/integrity')
-rw-r--r--security/integrity/digsig.c7
-rw-r--r--security/integrity/digsig_asymmetric.c11
-rw-r--r--security/integrity/evm/evm_main.c4
-rw-r--r--security/integrity/evm/evm_posix_acl.c3
-rw-r--r--security/integrity/iint.c2
-rw-r--r--security/integrity/ima/Kconfig64
-rw-r--r--security/integrity/ima/Makefile2
-rw-r--r--security/integrity/ima/ima.h106
-rw-r--r--security/integrity/ima/ima_api.c154
-rw-r--r--security/integrity/ima/ima_appraise.c106
-rw-r--r--security/integrity/ima/ima_crypto.c141
-rw-r--r--security/integrity/ima/ima_fs.c75
-rw-r--r--security/integrity/ima/ima_init.c40
-rw-r--r--security/integrity/ima/ima_main.c63
-rw-r--r--security/integrity/ima/ima_policy.c1
-rw-r--r--security/integrity/ima/ima_queue.c10
-rw-r--r--security/integrity/ima/ima_template.c187
-rw-r--r--security/integrity/ima/ima_template_lib.c351
-rw-r--r--security/integrity/ima/ima_template_lib.h49
-rw-r--r--security/integrity/integrity.h40
20 files changed, 185 insertions, 1231 deletions
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index b4af4eb..0b759e1 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -28,7 +28,7 @@ static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
};
int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
- const char *digest, int digestlen)
+ const char *digest, int digestlen)
{
if (id >= INTEGRITY_KEYRING_MAX)
return -EINVAL;
@@ -44,10 +44,9 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
}
}
- switch (sig[1]) {
+ switch (sig[0]) {
case 1:
- /* v1 API expect signature without xattr type */
- return digsig_verify(keyring[id], sig + 1, siglen - 1,
+ return digsig_verify(keyring[id], sig, siglen,
digest, digestlen);
case 2:
return asymmetric_verify(keyring[id], sig, siglen,
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index 9eae480..b475466 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -20,6 +20,17 @@
#include "integrity.h"
/*
+ * signature format v2 - for using with asymmetric keys
+ */
+struct signature_v2_hdr {
+ uint8_t version; /* signature format version */
+ uint8_t hash_algo; /* Digest algorithm [enum pkey_hash_algo] */
+ uint32_t keyid; /* IMA key identifier - not X509/PGP specific*/
+ uint16_t sig_size; /* signature size */
+ uint8_t sig[0]; /* signature payload */
+} __packed;
+
+/*
* Request an asymmetric key.
*/
static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 336b3dd..af9b685 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -123,7 +123,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
goto out;
}
- xattr_len = rc;
+ xattr_len = rc - 1;
/* check value type */
switch (xattr_data->type) {
@@ -143,7 +143,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
if (rc)
break;
rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
- (const char *)xattr_data, xattr_len,
+ xattr_data->digest, xattr_len,
calc.digest, sizeof(calc.digest));
if (!rc) {
/* we probably want to replace rsa with hmac here */
diff --git a/security/integrity/evm/evm_posix_acl.c b/security/integrity/evm/evm_posix_acl.c
index 46408b9..b1753e9 100644
--- a/security/integrity/evm/evm_posix_acl.c
+++ b/security/integrity/evm/evm_posix_acl.c
@@ -11,9 +11,8 @@
#include <linux/module.h>
#include <linux/xattr.h>
-#include <linux/evm.h>
-int posix_xattr_acl(const char *xattr)
+int posix_xattr_acl(char *xattr)
{
int xattr_len = strlen(xattr);
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index c49d3f1..74522db 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -70,8 +70,6 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
static void iint_free(struct integrity_iint_cache *iint)
{
- kfree(iint->ima_hash);
- iint->ima_hash = NULL;
iint->version = 0;
iint->flags = 0UL;
iint->ima_file_status = INTEGRITY_UNKNOWN;
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 81a2797..39196ab 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -9,7 +9,6 @@ config IMA
select CRYPTO_HMAC
select CRYPTO_MD5
select CRYPTO_SHA1
- select CRYPTO_HASH_INFO
select TCG_TPM if HAS_IOMEM && !UML
select TCG_TIS if TCG_TPM && X86
select TCG_IBMVTPM if TCG_TPM && PPC64
@@ -46,69 +45,6 @@ config IMA_LSM_RULES
help
Disabling this option will disregard LSM based policy rules.
-choice
- prompt "Default template"
- default IMA_NG_TEMPLATE
- depends on IMA
- help
- Select the default IMA measurement template.
-
- The original 'ima' measurement list template contains a
- hash, defined as 20 bytes, and a null terminated pathname,
- limited to 255 characters. The 'ima-ng' measurement list
- template permits both larger hash digests and longer
- pathnames.
-
- config IMA_TEMPLATE
- bool "ima"
- config IMA_NG_TEMPLATE
- bool "ima-ng (default)"
- config IMA_SIG_TEMPLATE
- bool "ima-sig"
-endchoice
-
-config IMA_DEFAULT_TEMPLATE
- string
- depends on IMA
- default "ima" if IMA_TEMPLATE
- default "ima-ng" if IMA_NG_TEMPLATE
- default "ima-sig" if IMA_SIG_TEMPLATE
-
-choice
- prompt "Default integrity hash algorithm"
- default IMA_DEFAULT_HASH_SHA1
- depends on IMA
- help
- Select the default hash algorithm used for the measurement
- list, integrity appraisal and audit log. The compiled default
- hash algorithm can be overwritten using the kernel command
- line 'ima_hash=' option.
-
- config IMA_DEFAULT_HASH_SHA1
- bool "SHA1 (default)"
- depends on CRYPTO_SHA1
-
- config IMA_DEFAULT_HASH_SHA256
- bool "SHA256"
- depends on CRYPTO_SHA256 && !IMA_TEMPLATE
-
- config IMA_DEFAULT_HASH_SHA512
- bool "SHA512"
- depends on CRYPTO_SHA512 && !IMA_TEMPLATE
-
- config IMA_DEFAULT_HASH_WP512
- bool "WP512"
- depends on CRYPTO_WP512 && !IMA_TEMPLATE
-endchoice
-
-config IMA_DEFAULT_HASH
- string
- depends on IMA
- default "sha1" if IMA_DEFAULT_HASH_SHA1
- default "sha256" if IMA_DEFAULT_HASH_SHA256
- default "sha512" if IMA_DEFAULT_HASH_SHA512
- default "wp512" if IMA_DEFAULT_HASH_WP512
-
config IMA_APPRAISE
bool "Appraise integrity measurements"
depends on IMA
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index d79263d..56dfee7 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -6,5 +6,5 @@
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_template.o ima_template_lib.o
+ ima_policy.o
ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 0356e1d..b3dd616 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -26,8 +26,7 @@
#include "../integrity.h"
-enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN,
- IMA_SHOW_ASCII };
+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 */
@@ -37,48 +36,23 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
#define IMA_HASH_BITS 9
#define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS)
-#define IMA_TEMPLATE_FIELD_ID_MAX_LEN 16
-#define IMA_TEMPLATE_NUM_FIELDS_MAX 15
-
-#define IMA_TEMPLATE_IMA_NAME "ima"
-#define IMA_TEMPLATE_IMA_FMT "d|n"
-
/* set during initialization */
extern int ima_initialized;
extern int ima_used_chip;
-extern int ima_hash_algo;
+extern char *ima_hash;
extern int ima_appraise;
-/* IMA template field data definition */
-struct ima_field_data {
- u8 *data;
- u32 len;
-};
-
-/* IMA template field definition */
-struct ima_template_field {
- const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN];
- int (*field_init) (struct integrity_iint_cache *iint, struct file *file,
- const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value,
- int xattr_len, struct ima_field_data *field_data);
- void (*field_show) (struct seq_file *m, enum ima_show_type show,
- struct ima_field_data *field_data);
-};
-
-/* IMA template descriptor definition */
-struct ima_template_desc {
- char *name;
- char *fmt;
- int num_fields;
- struct ima_template_field **fields;
+/* 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[TPM_DIGEST_SIZE]; /* sha1 or md5 measurement hash */
- struct ima_template_desc *template_desc; /* template descriptor */
- u32 template_data_len;
- struct ima_field_data template_data[0]; /* template related data */
+ 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 {
@@ -95,22 +69,13 @@ 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,
- const unsigned char *filename);
-int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash);
-int ima_calc_field_array_hash(struct ima_field_data *field_data,
- struct ima_template_desc *desc, int num_fields,
- struct ima_digest_data *hash);
-int __init ima_calc_boot_aggregate(struct ima_digest_data *hash);
-void ima_add_violation(struct file *file, const unsigned char *filename,
+ const char *op, struct inode *inode);
+int ima_calc_file_hash(struct file *file, char *digest);
+int ima_calc_buffer_hash(const void *data, int len, 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);
int ima_init_crypto(void);
-void ima_putc(struct seq_file *m, void *data, int datalen);
-void ima_print_digest(struct seq_file *m, u8 *digest, int size);
-struct ima_template_desc *ima_template_desc_current(void);
-int ima_init_template(void);
-
-int ima_init_template(void);
/*
* used to protect h_table and sha_table
@@ -133,22 +98,14 @@ static inline unsigned long ima_hash_key(u8 *digest)
int ima_get_action(struct inode *inode, int mask, int function);
int ima_must_measure(struct inode *inode, int mask, int function);
int ima_collect_measurement(struct integrity_iint_cache *iint,
- struct file *file,
- struct evm_ima_xattr_data **xattr_value,
- int *xattr_len);
+ struct file *file);
void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
- const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value,
- int xattr_len);
+ const unsigned char *filename);
void ima_audit_measurement(struct integrity_iint_cache *iint,
const unsigned char *filename);
-int ima_alloc_init_template(struct integrity_iint_cache *iint,
- struct file *file, const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value,
- int xattr_len, struct ima_template_entry **entry);
int ima_store_template(struct ima_template_entry *entry, int violation,
- struct inode *inode, const unsigned char *filename);
-void ima_free_template_entry(struct ima_template_entry *entry);
+ struct inode *inode);
+void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show);
const char *ima_d_path(struct path *path, char **pathbuf);
/* rbtree tree calls to lookup, insert, delete
@@ -174,25 +131,17 @@ void ima_delete_rules(void);
#ifdef CONFIG_IMA_APPRAISE
int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
- struct file *file, const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value,
- int xattr_len);
+ struct file *file, const unsigned char *filename);
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);
enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
int func);
-void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len,
- struct ima_digest_data *hash);
-int ima_read_xattr(struct dentry *dentry,
- struct evm_ima_xattr_data **xattr_value);
#else
static inline int ima_appraise_measurement(int func,
struct integrity_iint_cache *iint,
struct file *file,
- const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value,
- int xattr_len)
+ const unsigned char *filename)
{
return INTEGRITY_UNKNOWN;
}
@@ -213,19 +162,6 @@ static inline enum integrity_status ima_get_cache_status(struct integrity_iint_c
{
return INTEGRITY_UNKNOWN;
}
-
-static inline void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
- int xattr_len,
- struct ima_digest_data *hash)
-{
-}
-
-static inline int ima_read_xattr(struct dentry *dentry,
- struct evm_ima_xattr_data **xattr_value)
-{
- return 0;
-}
-
#endif
/* LSM based policy rules require audit */
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index c38bbce..1c03e8f1 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -18,59 +18,9 @@
#include <linux/fs.h>
#include <linux/xattr.h>
#include <linux/evm.h>
-#include <crypto/hash_info.h>
#include "ima.h"
-/*
- * ima_free_template_entry - free an existing template entry
- */
-void ima_free_template_entry(struct ima_template_entry *entry)
-{
- int i;
-
- for (i = 0; i < entry->template_desc->num_fields; i++)
- kfree(entry->template_data[i].data);
-
- kfree(entry);
-}
-
-/*
- * ima_alloc_init_template - create and initialize a new template entry
- */
-int ima_alloc_init_template(struct integrity_iint_cache *iint,
- struct file *file, const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value,
- int xattr_len, struct ima_template_entry **entry)
-{
- struct ima_template_desc *template_desc = ima_template_desc_current();
- int i, result = 0;
-
- *entry = kzalloc(sizeof(**entry) + template_desc->num_fields *
- sizeof(struct ima_field_data), GFP_NOFS);
- if (!*entry)
- return -ENOMEM;
-
- (*entry)->template_desc = template_desc;
- for (i = 0; i < template_desc->num_fields; i++) {
- struct ima_template_field *field = template_desc->fields[i];
- u32 len;
-
- result = field->field_init(iint, file, filename,
- xattr_value, xattr_len,
- &((*entry)->template_data[i]));
- if (result != 0)
- goto out;
-
- len = (*entry)->template_data[i].len;
- (*entry)->template_data_len += sizeof(len);
- (*entry)->template_data_len += len;
- }
- return 0;
-out:
- ima_free_template_entry(*entry);
- *entry = NULL;
- return result;
-}
+static const char *IMA_TEMPLATE_NAME = "ima";
/*
* ima_store_template - store ima template measurements
@@ -89,35 +39,28 @@ out:
* Returns 0 on success, error code otherwise
*/
int ima_store_template(struct ima_template_entry *entry,
- int violation, struct inode *inode,
- const unsigned char *filename)
+ int violation, struct inode *inode)
{
const char *op = "add_template_measure";
const char *audit_cause = "hashing_error";
- char *template_name = entry->template_desc->name;
int result;
- struct {
- struct ima_digest_data hdr;
- char digest[TPM_DIGEST_SIZE];
- } hash;
- if (!violation) {
- int num_fields = entry->template_desc->num_fields;
+ memset(entry->digest, 0, sizeof(entry->digest));
+ entry->template_name = IMA_TEMPLATE_NAME;
+ entry->template_len = sizeof(entry->template);
- /* this function uses default algo */
- hash.hdr.algo = HASH_ALGO_SHA1;
- result = ima_calc_field_array_hash(&entry->template_data[0],
- entry->template_desc,
- num_fields, &hash.hdr);
+ if (!violation) {
+ result = ima_calc_buffer_hash(&entry->template,
+ entry->template_len,
+ entry->digest);
if (result < 0) {
integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
- template_name, op,
+ entry->template_name, op,
audit_cause, result, 0);
return result;
}
- memcpy(entry->digest, hash.hdr.digest, hash.hdr.length);
}
- result = ima_add_template_entry(entry, violation, op, inode, filename);
+ result = ima_add_template_entry(entry, violation, op, inode);
return result;
}
@@ -128,26 +71,26 @@ int ima_store_template(struct ima_template_entry *entry,
* By extending the PCR with 0xFF's instead of with zeroes, the PCR
* value is invalidated.
*/
-void ima_add_violation(struct file *file, const unsigned char *filename,
+void ima_add_violation(struct inode *inode, const unsigned char *filename,
const char *op, const char *cause)
{
struct ima_template_entry *entry;
- struct inode *inode = file->f_dentry->d_inode;
int violation = 1;
int result;
/* can overflow, only indicator */
atomic_long_inc(&ima_htable.violations);
- result = ima_alloc_init_template(NULL, file, filename,
- NULL, 0, &entry);
- if (result < 0) {
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry) {
result = -ENOMEM;
goto err_out;
}
- result = ima_store_template(entry, violation, inode, filename);
+ 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)
- ima_free_template_entry(entry);
+ kfree(entry);
err_out:
integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
op, cause, result, 0);
@@ -195,42 +138,20 @@ int ima_must_measure(struct inode *inode, int mask, int function)
* Return 0 on success, error code otherwise
*/
int ima_collect_measurement(struct integrity_iint_cache *iint,
- struct file *file,
- struct evm_ima_xattr_data **xattr_value,
- int *xattr_len)
+ struct file *file)
{
struct inode *inode = file_inode(file);
const char *filename = file->f_dentry->d_name.name;
int result = 0;
- struct {
- struct ima_digest_data hdr;
- char digest[IMA_MAX_DIGEST_SIZE];
- } hash;
-
- if (xattr_value)
- *xattr_len = ima_read_xattr(file->f_dentry, xattr_value);
if (!(iint->flags & IMA_COLLECTED)) {
u64 i_version = file_inode(file)->i_version;
- /* use default hash algorithm */
- hash.hdr.algo = ima_hash_algo;
-
- if (xattr_value)
- ima_get_hash_algo(*xattr_value, *xattr_len, &hash.hdr);
-
- result = ima_calc_file_hash(file, &hash.hdr);
+ iint->ima_xattr.type = IMA_XATTR_DIGEST;
+ result = ima_calc_file_hash(file, iint->ima_xattr.digest);
if (!result) {
- int length = sizeof(hash.hdr) + hash.hdr.length;
- void *tmpbuf = krealloc(iint->ima_hash, length,
- GFP_NOFS);
- if (tmpbuf) {
- iint->ima_hash = tmpbuf;
- memcpy(iint->ima_hash, &hash, length);
- iint->version = i_version;
- iint->flags |= IMA_COLLECTED;
- } else
- result = -ENOMEM;
+ iint->version = i_version;
+ iint->flags |= IMA_COLLECTED;
}
}
if (result)
@@ -256,9 +177,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
* Must be called with iint->mutex held.
*/
void ima_store_measurement(struct integrity_iint_cache *iint,
- struct file *file, const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value,
- int xattr_len)
+ struct file *file, const unsigned char *filename)
{
const char *op = "add_template_measure";
const char *audit_cause = "ENOMEM";
@@ -270,35 +189,37 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
if (iint->flags & IMA_MEASURED)
return;
- result = ima_alloc_init_template(iint, file, filename,
- xattr_value, xattr_len, &entry);
- if (result < 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->ima_xattr.digest, IMA_DIGEST_SIZE);
+ strcpy(entry->template.file_name,
+ (strlen(filename) > IMA_EVENT_NAME_LEN_MAX) ?
+ file->f_dentry->d_name.name : filename);
- result = ima_store_template(entry, violation, inode, filename);
+ result = ima_store_template(entry, violation, inode);
if (!result || result == -EEXIST)
iint->flags |= IMA_MEASURED;
if (result < 0)
- ima_free_template_entry(entry);
+ kfree(entry);
}
void ima_audit_measurement(struct integrity_iint_cache *iint,
const unsigned char *filename)
{
struct audit_buffer *ab;
- char hash[(iint->ima_hash->length * 2) + 1];
- const char *algo_name = hash_algo_name[iint->ima_hash->algo];
- char algo_hash[sizeof(hash) + strlen(algo_name) + 2];
+ char hash[(IMA_DIGEST_SIZE * 2) + 1];
int i;
if (iint->flags & IMA_AUDITED)
return;
- for (i = 0; i < iint->ima_hash->length; i++)
- hex_byte_pack(hash + (i * 2), iint->ima_hash->digest[i]);
+ for (i = 0; i < IMA_DIGEST_SIZE; i++)
+ hex_byte_pack(hash + (i * 2), iint->ima_xattr.digest[i]);
hash[i * 2] = '\0';
ab = audit_log_start(current->audit_context, GFP_KERNEL,
@@ -309,8 +230,7 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
audit_log_format(ab, "file=");
audit_log_untrustedstring(ab, filename);
audit_log_format(ab, " hash=");
- snprintf(algo_hash, sizeof(algo_hash), "%s:%s", algo_name, hash);
- audit_log_untrustedstring(ab, algo_hash);
+ audit_log_untrustedstring(ab, hash);
audit_log_task_info(ab, current);
audit_log_end(ab);
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 734e946..2d4beca 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -15,7 +15,6 @@
#include <linux/magic.h>
#include <linux/ima.h>
#include <linux/evm.h>
-#include <crypto/hash_info.h>
#include "ima.h"
@@ -44,31 +43,19 @@ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
}
static int ima_fix_xattr(struct dentry *dentry,
- struct integrity_iint_cache *iint)
+ struct integrity_iint_cache *iint)
{
- int rc, offset;
- u8 algo = iint->ima_hash->algo;
-
- if (algo <= HASH_ALGO_SHA1) {
- offset = 1;
- iint->ima_hash->xattr.sha1.type = IMA_XATTR_DIGEST;
- } else {
- offset = 0;
- iint->ima_hash->xattr.ng.type = IMA_XATTR_DIGEST_NG;
- iint->ima_hash->xattr.ng.algo = algo;
- }
- rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA,
- &iint->ima_hash->xattr.data[offset],
- (sizeof(iint->ima_hash->xattr) - offset) +
- iint->ima_hash->length, 0);
- return rc;
+ iint->ima_xattr.type = IMA_XATTR_DIGEST;
+ return __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA,
+ (u8 *)&iint->ima_xattr,
+ sizeof(iint->ima_xattr), 0);
}
/* Return specific func appraised cached result */
enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
int func)
{
- switch (func) {
+ switch(func) {
case MMAP_CHECK:
return iint->ima_mmap_status;
case BPRM_CHECK:
@@ -84,7 +71,7 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
static void ima_set_cache_status(struct integrity_iint_cache *iint,
int func, enum integrity_status status)
{
- switch (func) {
+ switch(func) {
case MMAP_CHECK:
iint->ima_mmap_status = status;
break;
@@ -103,7 +90,7 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint,
static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
{
- switch (func) {
+ switch(func) {
case MMAP_CHECK:
iint->flags |= (IMA_MMAP_APPRAISED | IMA_APPRAISED);
break;
@@ -120,50 +107,6 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
}
}
-void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len,
- struct ima_digest_data *hash)
-{
- struct signature_v2_hdr *sig;
-
- if (!xattr_value || xattr_len < 2)
- return;
-
- switch (xattr_value->type) {
- case EVM_IMA_XATTR_DIGSIG:
- sig = (typeof(sig))xattr_value;
- if (sig->version != 2 || xattr_len <= sizeof(*sig))
- return;
- hash->algo = sig->hash_algo;
- break;
- case IMA_XATTR_DIGEST_NG:
- hash->algo = xattr_value->digest[0];
- break;
- case IMA_XATTR_DIGEST:
- /* this is for backward compatibility */
- if (xattr_len == 21) {
- unsigned int zero = 0;
- if (!memcmp(&xattr_value->digest[16], &zero, 4))
- hash->algo = HASH_ALGO_MD5;
- else
- hash->algo = HASH_ALGO_SHA1;
- } else if (xattr_len == 17)
- hash->algo = HASH_ALGO_MD5;
- break;
- }
-}
-
-int ima_read_xattr(struct dentry *dentry,
- struct evm_ima_xattr_data **xattr_value)
-{
- struct inode *inode = dentry->d_inode;
-
- if (!inode->i_op->getxattr)
- return 0;
-
- return vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value,
- 0, GFP_NOFS);
-}
-
/*
* ima_appraise_measurement - appraise file measurement
*
@@ -173,22 +116,23 @@ int ima_read_xattr(struct dentry *dentry,
* Return 0 on success, error code otherwise
*/
int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
- struct file *file, const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value,
- int xattr_len)
+ struct file *file, const unsigned char *filename)
{
struct dentry *dentry = file->f_dentry;
struct inode *inode = dentry->d_inode;
+ struct evm_ima_xattr_data *xattr_value = NULL;
enum integrity_status status = INTEGRITY_UNKNOWN;
const char *op = "appraise_data";
char *cause = "unknown";
- int rc = xattr_len, hash_start = 0;
+ int rc;
if (!ima_appraise)
return 0;
if (!inode->i_op->getxattr)
return INTEGRITY_UNKNOWN;
+ rc = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)&xattr_value,
+ 0, GFP_NOFS);
if (rc <= 0) {
if (rc && rc != -ENODATA)
goto out;
@@ -209,25 +153,14 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
goto out;
}
switch (xattr_value->type) {
- case IMA_XATTR_DIGEST_NG:
- /* first byte contains algorithm id */
- hash_start = 1;
case IMA_XATTR_DIGEST:
if (iint->flags & IMA_DIGSIG_REQUIRED) {
cause = "IMA signature required";
status = INTEGRITY_FAIL;
break;
}
- if (xattr_len - sizeof(xattr_value->type) - hash_start >=
- iint->ima_hash->length)
- /* xattr length may be longer. md5 hash in previous
- version occupied 20 bytes in xattr, instead of 16
- */
- rc = memcmp(&xattr_value->digest[hash_start],
- iint->ima_hash->digest,
- iint->ima_hash->length);
- else
- rc = -EINVAL;
+ rc = memcmp(xattr_value->digest, iint->ima_xattr.digest,
+ IMA_DIGEST_SIZE);
if (rc) {
cause = "invalid-hash";
status = INTEGRITY_FAIL;
@@ -238,9 +171,9 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
case EVM_IMA_XATTR_DIGSIG:
iint->flags |= IMA_DIGSIG;
rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
- (const char *)xattr_value, rc,
- iint->ima_hash->digest,
- iint->ima_hash->length);
+ xattr_value->digest, rc - 1,
+ iint->ima_xattr.digest,
+ IMA_DIGEST_SIZE);
if (rc == -EOPNOTSUPP) {
status = INTEGRITY_UNKNOWN;
} else if (rc) {
@@ -270,6 +203,7 @@ out:
ima_cache_flags(iint, func);
}
ima_set_cache_status(iint, func, status);
+ kfree(xattr_value);
return status;
}
@@ -285,7 +219,7 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
if (iint->flags & IMA_DIGSIG)
return;
- rc = ima_collect_measurement(iint, file, NULL, NULL);
+ rc = ima_collect_measurement(iint, file);
if (rc < 0)
return;
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index fdf60de..a02e079 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -20,7 +20,6 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <crypto/hash.h>
-#include <crypto/hash_info.h>
#include "ima.h"
static struct crypto_shash *ima_shash_tfm;
@@ -29,58 +28,31 @@ int ima_init_crypto(void)
{
long rc;
- ima_shash_tfm = crypto_alloc_shash(hash_algo_name[ima_hash_algo], 0, 0);
+ ima_shash_tfm = crypto_alloc_shash(ima_hash, 0, 0);
if (IS_ERR(ima_shash_tfm)) {
rc = PTR_ERR(ima_shash_tfm);
- pr_err("Can not allocate %s (reason: %ld)\n",
- hash_algo_name[ima_hash_algo], rc);
+ pr_err("Can not allocate %s (reason: %ld)\n", ima_hash, rc);
return rc;
}
return 0;
}
-static struct crypto_shash *ima_alloc_tfm(enum hash_algo algo)
-{
- struct crypto_shash *tfm = ima_shash_tfm;
- int rc;
-
- if (algo != ima_hash_algo && algo < HASH_ALGO__LAST) {
- tfm = crypto_alloc_shash(hash_algo_name[algo], 0, 0);
- if (IS_ERR(tfm)) {
- rc = PTR_ERR(tfm);
- pr_err("Can not allocate %s (reason: %d)\n",
- hash_algo_name[algo], rc);
- }
- }
- return tfm;
-}
-
-static void ima_free_tfm(struct crypto_shash *tfm)
-{
- if (tfm != ima_shash_tfm)
- crypto_free_shash(tfm);
-}
-
/*
* Calculate the MD5/SHA1 file digest
*/
-static int ima_calc_file_hash_tfm(struct file *file,
- struct ima_digest_data *hash,
- struct crypto_shash *tfm)
+int ima_calc_file_hash(struct file *file, char *digest)
{
loff_t i_size, offset = 0;
char *rbuf;
int rc, read = 0;
struct {
struct shash_desc shash;
- char ctx[crypto_shash_descsize(tfm)];
+ char ctx[crypto_shash_descsize(ima_shash_tfm)];
} desc;
- desc.shash.tfm = tfm;
+ desc.shash.tfm = ima_shash_tfm;
desc.shash.flags = 0;
- hash->length = crypto_shash_digestsize(tfm);
-
rc = crypto_shash_init(&desc.shash);
if (rc != 0)
return rc;
@@ -113,90 +85,27 @@ static int ima_calc_file_hash_tfm(struct file *file,
}
kfree(rbuf);
if (!rc)
- rc = crypto_shash_final(&desc.shash, hash->digest);
+ rc = crypto_shash_final(&desc.shash, digest);
if (read)
file->f_mode &= ~FMODE_READ;
out:
return rc;
}
-int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
-{
- struct crypto_shash *tfm;
- int rc;
-
- tfm = ima_alloc_tfm(hash->algo);
- if (IS_ERR(tfm))
- return PTR_ERR(tfm);
-
- rc = ima_calc_file_hash_tfm(file, hash, tfm);
-
- ima_free_tfm(tfm);
-
- return rc;
-}
-
/*
- * Calculate the hash of template data
+ * Calculate the hash of a given buffer
*/
-static int ima_calc_field_array_hash_tfm(struct ima_field_data *field_data,
- struct ima_template_desc *td,
- int num_fields,
- struct ima_digest_data *hash,
- struct crypto_shash *tfm)
+int ima_calc_buffer_hash(const void *data, int len, char *digest)
{
struct {
struct shash_desc shash;
- char ctx[crypto_shash_descsize(tfm)];
+ char ctx[crypto_shash_descsize(ima_shash_tfm)];
} desc;
- int rc, i;
- desc.shash.tfm = tfm;
+ desc.shash.tfm = ima_shash_tfm;
desc.shash.flags = 0;
- hash->length = crypto_shash_digestsize(tfm);
-
- rc = crypto_shash_init(&desc.shash);
- if (rc != 0)
- return rc;
-
- for (i = 0; i < num_fields; i++) {
- if (strcmp(td->name, IMA_TEMPLATE_IMA_NAME) != 0) {
- rc = crypto_shash_update(&desc.shash,
- (const u8 *) &field_data[i].len,
- sizeof(field_data[i].len));
- if (rc)
- break;
- }
- rc = crypto_shash_update(&desc.shash, field_data[i].data,
- field_data[i].len);
- if (rc)
- break;
- }
-
- if (!rc)
- rc = crypto_shash_final(&desc.shash, hash->digest);
-
- return rc;
-}
-
-int ima_calc_field_array_hash(struct ima_field_data *field_data,
- struct ima_template_desc *desc, int num_fields,
- struct ima_digest_data *hash)
-{
- struct crypto_shash *tfm;
- int rc;
-
- tfm = ima_alloc_tfm(hash->algo);
- if (IS_ERR(tfm))
- return PTR_ERR(tfm);
-
- rc = ima_calc_field_array_hash_tfm(field_data, desc, num_fields,
- hash, tfm);
-
- ima_free_tfm(tfm);
-
- return rc;
+ return crypto_shash_digest(&desc.shash, data, len, digest);
}
static void __init ima_pcrread(int idx, u8 *pcr)
@@ -211,17 +120,16 @@ static void __init ima_pcrread(int idx, u8 *pcr)
/*
* Calculate the boot aggregate hash
*/
-static int __init ima_calc_boot_aggregate_tfm(char *digest,
- struct crypto_shash *tfm)
+int __init ima_calc_boot_aggregate(char *digest)
{
- u8 pcr_i[TPM_DIGEST_SIZE];
+ u8 pcr_i[IMA_DIGEST_SIZE];
int rc, i;
struct {
struct shash_desc shash;
- char ctx[crypto_shash_descsize(tfm)];
+ char ctx[crypto_shash_descsize(ima_shash_tfm)];
} desc;
- desc.shash.tfm = tfm;
+ desc.shash.tfm = ima_shash_tfm;
desc.shash.flags = 0;
rc = crypto_shash_init(&desc.shash);
@@ -232,26 +140,9 @@ static int __init ima_calc_boot_aggregate_tfm(char *digest,
for (i = TPM_PCR0; i < TPM_PCR8; i++) {
ima_pcrread(i, pcr_i);
/* now accumulate with current aggregate */
- rc = crypto_shash_update(&desc.shash, pcr_i, TPM_DIGEST_SIZE);
+ rc = crypto_shash_update(&desc.shash, pcr_i, IMA_DIGEST_SIZE);
}
if (!rc)
crypto_shash_final(&desc.shash, digest);
return rc;
}
-
-int __init ima_calc_boot_aggregate(struct ima_digest_data *hash)
-{
- struct crypto_shash *tfm;
- int rc;
-
- tfm = ima_alloc_tfm(hash->algo);
- if (IS_ERR(tfm))
- return PTR_ERR(tfm);
-
- hash->length = crypto_shash_digestsize(tfm);
- rc = ima_calc_boot_aggregate_tfm(hash->digest, tfm);
-
- ima_free_tfm(tfm);
-
- return rc;
-}
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index db01125..38477c9 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -88,7 +88,8 @@ static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos)
* against concurrent list-extension
*/
rcu_read_lock();
- qe = list_entry_rcu(qe->later.next, struct ima_queue_entry, later);
+ qe = list_entry_rcu(qe->later.next,
+ struct ima_queue_entry, later);
rcu_read_unlock();
(*pos)++;
@@ -99,7 +100,7 @@ static void ima_measurements_stop(struct seq_file *m, void *v)
{
}
-void ima_putc(struct seq_file *m, void *data, int datalen)
+static void ima_putc(struct seq_file *m, void *data, int datalen)
{
while (datalen--)
seq_putc(m, *(char *)data++);
@@ -110,7 +111,6 @@ void ima_putc(struct seq_file *m, void *data, int datalen)
* char[20]=template digest
* 32bit-le=template name size
* char[n]=template name
- * [eventdata length]
* eventdata[n]=template specific data
*/
static int ima_measurements_show(struct seq_file *m, void *v)
@@ -120,8 +120,6 @@ static int ima_measurements_show(struct seq_file *m, void *v)
struct ima_template_entry *e;
int namelen;
u32 pcr = CONFIG_IMA_MEASURE_PCR_IDX;
- bool is_ima_template = false;
- int i;
/* get entry */
e = qe->entry;
@@ -136,32 +134,18 @@ static int ima_measurements_show(struct seq_file *m, void *v)
ima_putc(m, &pcr, sizeof pcr);
/* 2nd: template digest */
- ima_putc(m, e->digest, TPM_DIGEST_SIZE);
+ ima_putc(m, e->digest, IMA_DIGEST_SIZE);
/* 3rd: template name size */
- namelen = strlen(e->template_desc->name);
+ namelen = strlen(e->template_name);
ima_putc(m, &namelen, sizeof namelen);
/* 4th: template name */
- ima_putc(m, e->template_desc->name, namelen);
-
- /* 5th: template length (except for 'ima' template) */
- if (strcmp(e->template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0)
- is_ima_template = true;
-
- if (!is_ima_template)
- ima_putc(m, &e->template_data_len,
- sizeof(e->template_data_len));
-
- /* 6th: template specific data */
- for (i = 0; i < e->template_desc->num_fields; i++) {
- enum ima_show_type show = IMA_SHOW_BINARY;
- struct ima_template_field *field = e->template_desc->fields[i];
+ ima_putc(m, (void *)e->template_name, namelen);
- if (is_ima_template && strcmp(field->field_id, "d") == 0)
- show = IMA_SHOW_BINARY_NO_FIELD_LEN;
- field->field_show(m, show, &e->template_data[i]);
- }
+ /* 5th: template specific data */
+ ima_template_show(m, (struct ima_template_data *)&e->template,
+ IMA_SHOW_BINARY);
return 0;
}
@@ -184,21 +168,41 @@ static const struct file_operations ima_measurements_ops = {
.release = seq_release,
};
-void ima_print_digest(struct seq_file *m, u8 *digest, int size)
+static void ima_print_digest(struct seq_file *m, u8 *digest)
{
int i;
- for (i = 0; i < size; 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;
- int i;
/* get entry */
e = qe->entry;
@@ -209,21 +213,14 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
seq_printf(m, "%2d ", CONFIG_IMA_MEASURE_PCR_IDX);
/* 2nd: SHA1 template hash */
- ima_print_digest(m, e->digest, TPM_DIGEST_SIZE);
+ ima_print_digest(m, e->digest);
/* 3th: template name */
- seq_printf(m, " %s", e->template_desc->name);
+ seq_printf(m, " %s ", e->template_name);
/* 4th: template specific data */
- for (i = 0; i < e->template_desc->num_fields; i++) {
- seq_puts(m, " ");
- if (e->template_data[i].len == 0)
- continue;
-
- e->template_desc->fields[i]->field_show(m, IMA_SHOW_ASCII,
- &e->template_data[i]);
- }
- seq_puts(m, "\n");
+ ima_template_show(m, (struct ima_template_data *)&e->template,
+ IMA_SHOW_ASCII);
return 0;
}
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 3712276..162ea72 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -18,7 +18,6 @@
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/err.h>
-#include <crypto/hash_info.h>
#include "ima.h"
/* name for boot aggregate entry */
@@ -43,39 +42,30 @@ int ima_used_chip;
static void __init ima_add_boot_aggregate(void)
{
struct ima_template_entry *entry;
- struct integrity_iint_cache tmp_iint, *iint = &tmp_iint;
const char *op = "add_boot_aggregate";
const char *audit_cause = "ENOMEM";
int result = -ENOMEM;
- int violation = 0;
- struct {
- struct ima_digest_data hdr;
- char digest[TPM_DIGEST_SIZE];
- } hash;
+ int violation = 1;
- memset(iint, 0, sizeof(*iint));
- memset(&hash, 0, sizeof(hash));
- iint->ima_hash = &hash.hdr;
- iint->ima_hash->algo = HASH_ALGO_SHA1;
- iint->ima_hash->length = SHA1_DIGEST_SIZE;
+ 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) {
- result = ima_calc_boot_aggregate(&hash.hdr);
+ violation = 0;
+ result = ima_calc_boot_aggregate(entry->template.digest);
if (result < 0) {
audit_cause = "hashing_error";
+ kfree(entry);
goto err_out;
}
}
-
- result = ima_alloc_init_template(iint, NULL, boot_aggregate_name,
- NULL, 0, &entry);
- if (result < 0)
- return;
-
- result = ima_store_template(entry, violation, NULL,
- boot_aggregate_name);
+ result = ima_store_template(entry, violation, NULL);
if (result < 0)
- ima_free_template_entry(entry);
+ kfree(entry);
return;
err_out:
integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op,
@@ -84,7 +74,7 @@ err_out:
int __init ima_init(void)
{
- u8 pcr_i[TPM_DIGEST_SIZE];
+ u8 pcr_i[IMA_DIGEST_SIZE];
int rc;
ima_used_chip = 0;
@@ -98,10 +88,6 @@ int __init ima_init(void)
rc = ima_init_crypto();
if (rc)
return rc;
- rc = ima_init_template();
- if (rc != 0)
- return rc;
-
ima_add_boot_aggregate(); /* boot aggregate must be first entry */
ima_init_policy();
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 149ee11..e9508d5 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -24,7 +24,6 @@
#include <linux/slab.h>
#include <linux/xattr.h>
#include <linux/ima.h>
-#include <crypto/hash_info.h>
#include "ima.h"
@@ -36,33 +35,11 @@ int ima_appraise = IMA_APPRAISE_ENFORCE;
int ima_appraise;
#endif
-int ima_hash_algo = HASH_ALGO_SHA1;
-static int hash_setup_done;
-
+char *ima_hash = "sha1";
static int __init hash_setup(char *str)
{
- struct ima_template_desc *template_desc = ima_template_desc_current();
- int i;
-
- if (hash_setup_done)
- return 1;
-
- if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) {
- if (strncmp(str, "sha1", 4) == 0)
- ima_hash_algo = HASH_ALGO_SHA1;
- else if (strncmp(str, "md5", 3) == 0)
- ima_hash_algo = HASH_ALGO_MD5;
- goto out;
- }
-
- for (i = 0; i < HASH_ALGO__LAST; i++) {
- if (strcmp(str, hash_algo_name[i]) == 0) {
- ima_hash_algo = i;
- break;
- }
- }
-out:
- hash_setup_done = 1;
+ if (strncmp(str, "md5", 3) == 0)
+ ima_hash = "md5";
return 1;
}
__setup("ima_hash=", hash_setup);
@@ -115,9 +92,10 @@ out:
pathname = dentry->d_name.name;
if (send_tomtou)
- ima_add_violation(file, pathname, "invalid_pcr", "ToMToU");
+ ima_add_violation(inode, pathname,
+ "invalid_pcr", "ToMToU");
if (send_writers)
- ima_add_violation(file, pathname,
+ ima_add_violation(inode, pathname,
"invalid_pcr", "open_writers");
kfree(pathbuf);
}
@@ -166,12 +144,9 @@ static int process_measurement(struct file *file, const char *filename,
{
struct inode *inode = file_inode(file);
struct integrity_iint_cache *iint;
- struct ima_template_desc *template_desc = ima_template_desc_current();
char *pathbuf = NULL;
const char *pathname = NULL;
int rc = -ENOMEM, action, must_appraise, _func;
- struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL;
- int xattr_len = 0;
if (!ima_initialized || !S_ISREG(inode->i_mode))
return 0;
@@ -210,13 +185,7 @@ static int process_measurement(struct file *file, const char *filename,
goto out_digsig;
}
- if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) {
- if (action & IMA_APPRAISE_SUBMASK)
- xattr_ptr = &xattr_value;
- } else
- xattr_ptr = &xattr_value;
-
- rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len);
+ rc = ima_collect_measurement(iint, file);
if (rc != 0)
goto out_digsig;
@@ -225,11 +194,9 @@ static int process_measurement(struct file *file, const char *filename,
pathname = (const char *)file->f_dentry->d_name.name;
if (action & IMA_MEASURE)
- ima_store_measurement(iint, file, pathname,
- xattr_value, xattr_len);
+ ima_store_measurement(iint, file, pathname);
if (action & IMA_APPRAISE_SUBMASK)
- rc = ima_appraise_measurement(_func, iint, file, pathname,
- xattr_value, xattr_len);
+ rc = ima_appraise_measurement(_func, iint, file, pathname);
if (action & IMA_AUDIT)
ima_audit_measurement(iint, pathname);
kfree(pathbuf);
@@ -238,7 +205,6 @@ out_digsig:
rc = -EACCES;
out:
mutex_unlock(&inode->i_mutex);
- kfree(xattr_value);
if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE))
return -EACCES;
return 0;
@@ -278,9 +244,9 @@ int ima_file_mmap(struct file *file, unsigned long prot)
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);
+ (strcmp(bprm->filename, bprm->interp) == 0) ?
+ bprm->filename : bprm->interp,
+ MAY_EXEC, BPRM_CHECK);
}
/**
@@ -297,8 +263,8 @@ int ima_file_check(struct file *file, int mask)
{
ima_rdwr_violation_check(file);
return process_measurement(file, NULL,
- mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
- FILE_CHECK);
+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
+ FILE_CHECK);
}
EXPORT_SYMBOL_GPL(ima_file_check);
@@ -328,7 +294,6 @@ static int __init init_ima(void)
{
int error;
- hash_setup(CONFIG_IMA_DEFAULT_HASH);
error = ima_init();
if (!error)
ima_initialized = 1;
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index a9c3d3c..399433a 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -73,6 +73,7 @@ static struct ima_rule_entry default_rules[] = {
{.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 = DEVPTS_SUPER_MAGIC,.flags = IMA_FSMAGIC},
{.action = DONT_MEASURE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC},
{.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index d85e997..ff63fe0 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -50,7 +50,7 @@ static struct ima_queue_entry *ima_lookup_digest_entry(u8 *digest_value)
key = ima_hash_key(digest_value);
rcu_read_lock();
hlist_for_each_entry_rcu(qe, &ima_htable.queue[key], hnext) {
- rc = memcmp(qe->entry->digest, digest_value, TPM_DIGEST_SIZE);
+ rc = memcmp(qe->entry->digest, digest_value, IMA_DIGEST_SIZE);
if (rc == 0) {
ret = qe;
break;
@@ -104,10 +104,9 @@ static int ima_pcr_extend(const u8 *hash)
* and extend the pcr.
*/
int ima_add_template_entry(struct ima_template_entry *entry, int violation,
- const char *op, struct inode *inode,
- const unsigned char *filename)
+ const char *op, struct inode *inode)
{
- u8 digest[TPM_DIGEST_SIZE];
+ u8 digest[IMA_DIGEST_SIZE];
const char *audit_cause = "hash_added";
char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX];
int audit_info = 1;
@@ -142,7 +141,8 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
}
out:
mutex_unlock(&ima_extend_list_mutex);
- integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
+ integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
+ entry->template.file_name,
op, audit_cause, result, audit_info);
return result;
}
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
deleted file mode 100644
index 635695f..0000000
--- a/security/integrity/ima/ima_template.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2013 Politecnico di Torino, Italy
- * TORSEC group -- http://security.polito.it
- *
- * Author: Roberto Sassu <roberto.sassu@polito.it>
- *
- * 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_template.c
- * Helpers to manage template descriptors.
- */
-#include <crypto/hash_info.h>
-
-#include "ima.h"
-#include "ima_template_lib.h"
-
-static struct ima_template_desc defined_templates[] = {
- {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT},
- {.name = "ima-ng",.fmt = "d-ng|n-ng"},
- {.name = "ima-sig",.fmt = "d-ng|n-ng|sig"},
-};
-
-static struct ima_template_field supported_fields[] = {
- {.field_id = "d",.field_init = ima_eventdigest_init,
- .field_show = ima_show_template_digest},
- {.field_id = "n",.field_init = ima_eventname_init,
- .field_show = ima_show_template_string},
- {.field_id = "d-ng",.field_init = ima_eventdigest_ng_init,
- .field_show = ima_show_template_digest_ng},
- {.field_id = "n-ng",.field_init = ima_eventname_ng_init,
- .field_show = ima_show_template_string},
- {.field_id = "sig",.field_init = ima_eventsig_init,
- .field_show = ima_show_template_sig},
-};
-
-static struct ima_template_desc *ima_template;
-static struct ima_template_desc *lookup_template_desc(const char *name);
-
-static int __init ima_template_setup(char *str)
-{
- struct ima_template_desc *template_desc;
- int template_len = strlen(str);
-
- /*
- * Verify that a template with the supplied name exists.
- * If not, use CONFIG_IMA_DEFAULT_TEMPLATE.
- */
- template_desc = lookup_template_desc(str);
- if (!template_desc)
- return 1;
-
- /*
- * Verify whether the current hash algorithm is supported
- * by the 'ima' template.
- */
- if (template_len == 3 && strcmp(str, IMA_TEMPLATE_IMA_NAME) == 0 &&
- ima_hash_algo != HASH_ALGO_SHA1 && ima_hash_algo != HASH_ALGO_MD5) {
- pr_err("IMA: template does not support hash alg\n");
- return 1;
- }
-
- ima_template = template_desc;
- return 1;
-}
-__setup("ima_template=", ima_template_setup);
-
-static struct ima_template_desc *lookup_template_desc(const char *name)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(defined_templates); i++) {
- if (strcmp(defined_templates[i].name, name) == 0)
- return defined_templates + i;
- }
-
- return NULL;
-}
-
-static struct ima_template_field *lookup_template_field(const char *field_id)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(supported_fields); i++)
- if (strncmp(supported_fields[i].field_id, field_id,
- IMA_TEMPLATE_FIELD_ID_MAX_LEN) == 0)
- return &supported_fields[i];
- return NULL;
-}
-
-static int template_fmt_size(const char *template_fmt)
-{
- char c;
- int template_fmt_len = strlen(template_fmt);
- int i = 0, j = 0;
-
- while (i < template_fmt_len) {
- c = template_fmt[i];
- if (c == '|')
- j++;
- i++;
- }
-
- return j + 1;
-}
-
-static int template_desc_init_fields(const char *template_fmt,
- struct ima_template_field ***fields,
- int *num_fields)
-{
- char *c, *template_fmt_copy, *template_fmt_ptr;
- int template_num_fields = template_fmt_size(template_fmt);
- int i, result = 0;
-
- if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX)
- return -EINVAL;
-
- /* copying is needed as strsep() modifies the original buffer */
- template_fmt_copy = kstrdup(template_fmt, GFP_KERNEL);
- if (template_fmt_copy == NULL)
- return -ENOMEM;
-
- *fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL);
- if (*fields == NULL) {
- result = -ENOMEM;
- goto out;
- }
-
- template_fmt_ptr = template_fmt_copy;
- for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL &&
- i < template_num_fields; i++) {
- struct ima_template_field *f = lookup_template_field(c);
-
- if (!f) {
- result = -ENOENT;
- goto out;
- }
- (*fields)[i] = f;
- }
- *num_fields = i;
-out:
- if (result < 0) {
- kfree(*fields);
- *fields = NULL;
- }
- kfree(template_fmt_copy);
- 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)
-{
- if (!ima_template)
- ima_template =
- lookup_template_desc(CONFIG_IMA_DEFAULT_TEMPLATE);
- return ima_template;
-}
-
-int ima_init_template(void)
-{
- int result;
-
- result = init_defined_templates();
- if (result < 0)
- return result;
-
- return 0;
-}
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
deleted file mode 100644
index c38adcc..0000000
--- a/security/integrity/ima/ima_template_lib.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Copyright (C) 2013 Politecnico di Torino, Italy
- * TORSEC group -- http://security.polito.it
- *
- * Author: Roberto Sassu <roberto.sassu@polito.it>
- *
- * 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_template_lib.c
- * Library of supported template fields.
- */
-#include <crypto/hash_info.h>
-
-#include "ima_template_lib.h"
-
-static bool ima_template_hash_algo_allowed(u8 algo)
-{
- if (algo == HASH_ALGO_SHA1 || algo == HASH_ALGO_MD5)
- return true;
-
- return false;
-}
-
-enum data_formats {
- DATA_FMT_DIGEST = 0,
- DATA_FMT_DIGEST_WITH_ALGO,
- DATA_FMT_EVENT_NAME,
- DATA_FMT_STRING,
- DATA_FMT_HEX
-};
-
-static int ima_write_template_field_data(const void *data, const u32 datalen,
- enum data_formats datafmt,
- struct ima_field_data *field_data)
-{
- u8 *buf, *buf_ptr;
- u32 buflen;
-
- switch (datafmt) {
- case DATA_FMT_EVENT_NAME:
- buflen = IMA_EVENT_NAME_LEN_MAX + 1;
- break;
- case DATA_FMT_STRING:
- buflen = datalen + 1;
- break;
- default:
- buflen = datalen;
- }
-
- buf = kzalloc(buflen, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- memcpy(buf, data, datalen);
-
- /*
- * Replace all space characters with underscore for event names and
- * strings. This avoid that, during the parsing of a measurements list,
- * filenames with spaces or that end with the suffix ' (deleted)' are
- * split into multiple template fields (the space is the delimitator
- * character for measurements lists in ASCII format).
- */
- if (datafmt == DATA_FMT_EVENT_NAME || datafmt == DATA_FMT_STRING) {
- for (buf_ptr = buf; buf_ptr - buf < datalen; buf_ptr++)
- if (*buf_ptr == ' ')
- *buf_ptr = '_';
- }
-
- field_data->data = buf;
- field_data->len = buflen;
- return 0;
-}
-
-static void ima_show_template_data_ascii(struct seq_file *m,
- enum ima_show_type show,
- enum data_formats datafmt,
- struct ima_field_data *field_data)
-{
- u8 *buf_ptr = field_data->data, buflen = field_data->len;
-
- switch (datafmt) {
- case DATA_FMT_DIGEST_WITH_ALGO:
- buf_ptr = strnchr(field_data->data, buflen, ':');
- if (buf_ptr != field_data->data)
- seq_printf(m, "%s", field_data->data);
-
- /* skip ':' and '\0' */
- buf_ptr += 2;
- buflen -= buf_ptr - field_data->data;
- case DATA_FMT_DIGEST:
- case DATA_FMT_HEX:
- if (!buflen)
- break;
- ima_print_digest(m, buf_ptr, buflen);
- break;
- case DATA_FMT_STRING:
- seq_printf(m, "%s", buf_ptr);
- break;
- default:
- break;
- }
-}
-
-static void ima_show_template_data_binary(struct seq_file *m,
- enum ima_show_type show,
- enum data_formats datafmt,
- struct ima_field_data *field_data)
-{
- if (show != IMA_SHOW_BINARY_NO_FIELD_LEN)
- ima_putc(m, &field_data->len, sizeof(u32));
-
- if (!field_data->len)
- return;
-
- ima_putc(m, field_data->data, field_data->len);
-}
-
-static void ima_show_template_field_data(struct seq_file *m,
- enum ima_show_type show,
- enum data_formats datafmt,
- struct ima_field_data *field_data)
-{
- switch (show) {
- case IMA_SHOW_ASCII:
- ima_show_template_data_ascii(m, show, datafmt, field_data);
- break;
- case IMA_SHOW_BINARY:
- case IMA_SHOW_BINARY_NO_FIELD_LEN:
- ima_show_template_data_binary(m, show, datafmt, field_data);
- break;
- default:
- break;
- }
-}
-
-void ima_show_template_digest(struct seq_file *m, enum ima_show_type show,
- struct ima_field_data *field_data)
-{
- ima_show_template_field_data(m, show, DATA_FMT_DIGEST, field_data);
-}
-
-void ima_show_template_digest_ng(struct seq_file *m, enum ima_show_type show,
- struct ima_field_data *field_data)
-{
- ima_show_template_field_data(m, show, DATA_FMT_DIGEST_WITH_ALGO,
- field_data);
-}
-
-void ima_show_template_string(struct seq_file *m, enum ima_show_type show,
- struct ima_field_data *field_data)
-{
- ima_show_template_field_data(m, show, DATA_FMT_STRING, field_data);
-}
-
-void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
- struct ima_field_data *field_data)
-{
- ima_show_template_field_data(m, show, DATA_FMT_HEX, field_data);
-}
-
-static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo,
- struct ima_field_data *field_data,
- bool size_limit)
-{
- /*
- * digest formats:
- * - DATA_FMT_DIGEST: digest
- * - DATA_FMT_DIGEST_WITH_ALGO: [<hash algo>] + ':' + '\0' + digest,
- * where <hash algo> is provided if the hash algoritm is not
- * SHA1 or MD5
- */
- u8 buffer[CRYPTO_MAX_ALG_NAME + 2 + IMA_MAX_DIGEST_SIZE] = { 0 };
- enum data_formats fmt = DATA_FMT_DIGEST;
- u32 offset = 0;
-
- if (!size_limit) {
- fmt = DATA_FMT_DIGEST_WITH_ALGO;
- if (hash_algo < HASH_ALGO__LAST)
- offset += snprintf(buffer, CRYPTO_MAX_ALG_NAME + 1,
- "%s", hash_algo_name[hash_algo]);
- buffer[offset] = ':';
- offset += 2;
- }
-
- if (digest)
- memcpy(buffer + offset, digest, digestsize);
- else
- /*
- * If digest is NULL, the event being recorded is a violation.
- * Make room for the digest by increasing the offset of
- * IMA_DIGEST_SIZE.
- */
- offset += IMA_DIGEST_SIZE;
-
- return ima_write_template_field_data(buffer, offset + digestsize,
- fmt, field_data);
-}
-
-/*
- * This function writes the digest of an event (with size limit).
- */
-int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
- const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value, int xattr_len,
- struct ima_field_data *field_data)
-{
- struct {
- struct ima_digest_data hdr;
- char digest[IMA_MAX_DIGEST_SIZE];
- } hash;
- u8 *cur_digest = NULL;
- u32 cur_digestsize = 0;
- struct inode *inode;
- int result;
-
- memset(&hash, 0, sizeof(hash));
-
- if (!iint) /* recording a violation. */
- goto out;
-
- if (ima_template_hash_algo_allowed(iint->ima_hash->algo)) {
- cur_digest = iint->ima_hash->digest;
- cur_digestsize = iint->ima_hash->length;
- goto out;
- }
-
- if (!file) /* missing info to re-calculate the digest */
- return -EINVAL;
-
- inode = file_inode(file);
- hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ?
- ima_hash_algo : HASH_ALGO_SHA1;
- result = ima_calc_file_hash(file, &hash.hdr);
- if (result) {
- integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
- filename, "collect_data",
- "failed", result, 0);
- return result;
- }
- cur_digest = hash.hdr.digest;
- cur_digestsize = hash.hdr.length;
-out:
- return ima_eventdigest_init_common(cur_digest, cur_digestsize, -1,
- field_data, true);
-}
-
-/*
- * This function writes the digest of an event (without size limit).
- */
-int ima_eventdigest_ng_init(struct integrity_iint_cache *iint,
- struct file *file, const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value,
- int xattr_len, struct ima_field_data *field_data)
-{
- u8 *cur_digest = NULL, hash_algo = HASH_ALGO__LAST;
- u32 cur_digestsize = 0;
-
- /* If iint is NULL, we are recording a violation. */
- if (!iint)
- goto out;
-
- cur_digest = iint->ima_hash->digest;
- cur_digestsize = iint->ima_hash->length;
-
- hash_algo = iint->ima_hash->algo;
-out:
- return ima_eventdigest_init_common(cur_digest, cur_digestsize,
- hash_algo, field_data, false);
-}
-
-static int ima_eventname_init_common(struct integrity_iint_cache *iint,
- struct file *file,
- const unsigned char *filename,
- struct ima_field_data *field_data,
- bool size_limit)
-{
- const char *cur_filename = NULL;
- u32 cur_filename_len = 0;
- enum data_formats fmt = size_limit ?
- DATA_FMT_EVENT_NAME : DATA_FMT_STRING;
-
- BUG_ON(filename == NULL && file == NULL);
-
- if (filename) {
- cur_filename = filename;
- cur_filename_len = strlen(filename);
-
- if (!size_limit || cur_filename_len <= IMA_EVENT_NAME_LEN_MAX)
- goto out;
- }
-
- if (file) {
- cur_filename = file->f_dentry->d_name.name;
- cur_filename_len = strlen(cur_filename);
- } else
- /*
- * Truncate filename if the latter is too long and
- * the file descriptor is not available.
- */
- cur_filename_len = IMA_EVENT_NAME_LEN_MAX;
-out:
- return ima_write_template_field_data(cur_filename, cur_filename_len,
- fmt, field_data);
-}
-
-/*
- * This function writes the name of an event (with size limit).
- */
-int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file,
- const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value, int xattr_len,
- struct ima_field_data *field_data)
-{
- return ima_eventname_init_common(iint, file, filename,
- field_data, true);
-}
-
-/*
- * This function writes the name of an event (without size limit).
- */
-int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file,
- const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value, int xattr_len,
- struct ima_field_data *field_data)
-{
- return ima_eventname_init_common(iint, file, filename,
- field_data, false);
-}
-
-/*
- * ima_eventsig_init - include the file signature as part of the template data
- */
-int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file,
- const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value, int xattr_len,
- struct ima_field_data *field_data)
-{
- enum data_formats fmt = DATA_FMT_HEX;
- int rc = 0;
-
- if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG))
- goto out;
-
- rc = ima_write_template_field_data(xattr_value, xattr_len, fmt,
- field_data);
-out:
- return rc;
-}
diff --git a/security/integrity/ima/ima_template_lib.h b/security/integrity/ima/ima_template_lib.h
deleted file mode 100644
index 63f6b52..0000000
--- a/security/integrity/ima/ima_template_lib.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2013 Politecnico di Torino, Italy
- * TORSEC group -- http://security.polito.it
- *
- * Author: Roberto Sassu <roberto.sassu@polito.it>
- *
- * 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_template_lib.h
- * Header for the library of supported template fields.
- */
-#ifndef __LINUX_IMA_TEMPLATE_LIB_H
-#define __LINUX_IMA_TEMPLATE_LIB_H
-
-#include <linux/seq_file.h>
-#include "ima.h"
-
-void ima_show_template_digest(struct seq_file *m, enum ima_show_type show,
- struct ima_field_data *field_data);
-void ima_show_template_digest_ng(struct seq_file *m, enum ima_show_type show,
- struct ima_field_data *field_data);
-void ima_show_template_string(struct seq_file *m, enum ima_show_type show,
- struct ima_field_data *field_data);
-void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
- struct ima_field_data *field_data);
-int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
- const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value, int xattr_len,
- struct ima_field_data *field_data);
-int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file,
- const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value, int xattr_len,
- struct ima_field_data *field_data);
-int ima_eventdigest_ng_init(struct integrity_iint_cache *iint,
- struct file *file, const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value,
- int xattr_len, struct ima_field_data *field_data);
-int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file,
- const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value, int xattr_len,
- struct ima_field_data *field_data);
-int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file,
- const unsigned char *filename,
- struct evm_ima_xattr_data *xattr_value, int xattr_len,
- struct ima_field_data *field_data);
-#endif /* __LINUX_IMA_TEMPLATE_LIB_H */
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 2fb5e53..c42fb7a 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -54,57 +54,25 @@ enum evm_ima_xattr_type {
IMA_XATTR_DIGEST = 0x01,
EVM_XATTR_HMAC,
EVM_IMA_XATTR_DIGSIG,
- IMA_XATTR_DIGEST_NG,
};
struct evm_ima_xattr_data {
u8 type;
u8 digest[SHA1_DIGEST_SIZE];
-} __packed;
-
-#define IMA_MAX_DIGEST_SIZE 64
-
-struct ima_digest_data {
- u8 algo;
- u8 length;
- union {
- struct {
- u8 unused;
- u8 type;
- } sha1;
- struct {
- u8 type;
- u8 algo;
- } ng;
- u8 data[2];
- } xattr;
- u8 digest[0];
-} __packed;
-
-/*
- * signature format v2 - for using with asymmetric keys
- */
-struct signature_v2_hdr {
- uint8_t type; /* xattr type */
- uint8_t version; /* signature format version */
- uint8_t hash_algo; /* Digest algorithm [enum pkey_hash_algo] */
- uint32_t keyid; /* IMA key identifier - not X509/PGP specific */
- uint16_t sig_size; /* signature size */
- uint8_t sig[0]; /* signature payload */
-} __packed;
+} __attribute__((packed));
/* integrity data associated with an inode */
struct integrity_iint_cache {
- struct rb_node rb_node; /* rooted in integrity_iint_tree */
+ 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 long flags;
+ struct evm_ima_xattr_data ima_xattr;
enum integrity_status ima_file_status:4;
enum integrity_status ima_mmap_status:4;
enum integrity_status ima_bprm_status:4;
enum integrity_status ima_module_status:4;
enum integrity_status evm_status:4;
- struct ima_digest_data *ima_hash;
};
/* rbtree tree calls to lookup, insert, delete
@@ -121,7 +89,7 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
#ifdef CONFIG_INTEGRITY_SIGNATURE
int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
- const char *digest, int digestlen);
+ const char *digest, int digestlen);
#else