Skip to content

Commit

Permalink
ima: maintain memory size needed for serializing the measurement list
Browse files Browse the repository at this point in the history
In preparation for serializing the binary_runtime_measurements, this
patch maintains the amount of memory required.

Link: http://lkml.kernel.org/r/1480554346-29071-5-git-send-email-zohar@linux.vnet.ibm.com
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Acked-by: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
Cc: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Andreas Steffen <andreas.steffen@strongswan.org>
Cc: Josh Sklar <sklar@linux.vnet.ibm.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Stewart Smith <stewart@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Mimi Zohar authored and torvalds committed Dec 20, 2016
1 parent dcfc569 commit d158847
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
12 changes: 12 additions & 0 deletions security/integrity/ima/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ config IMA
to learn more about IMA.
If unsure, say N.

config IMA_KEXEC
bool "Enable carrying the IMA measurement list across a soft boot"
depends on IMA && TCG_TPM && HAVE_IMA_KEXEC
default n
help
TPM PCRs are only reset on a hard reboot. In order to validate
a TPM's quote after a soft boot, the IMA measurement list of the
running kernel must be saved and restored on boot.

Depending on the IMA policy, the measurement list can grow to
be very large.

config IMA_MEASURE_PCR_IDX
int
depends on IMA
Expand Down
1 change: 1 addition & 0 deletions security/integrity/ima/ima.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ void ima_print_digest(struct seq_file *m, u8 *digest, u32 size);
struct ima_template_desc *ima_template_desc_current(void);
int ima_restore_measurement_entry(struct ima_template_entry *entry);
int ima_restore_measurement_list(loff_t bufsize, void *buf);
unsigned long ima_get_binary_runtime_size(void);
int ima_init_template(void);

/*
Expand Down
53 changes: 51 additions & 2 deletions security/integrity/ima/ima_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
#define AUDIT_CAUSE_LEN_MAX 32

LIST_HEAD(ima_measurements); /* list of all measurements */
#ifdef CONFIG_IMA_KEXEC
static unsigned long binary_runtime_size;
#else
static unsigned long binary_runtime_size = ULONG_MAX;
#endif

/* key: inode (before secure-hashing a file) */
struct ima_h_table ima_htable = {
Expand Down Expand Up @@ -64,6 +69,24 @@ static struct ima_queue_entry *ima_lookup_digest_entry(u8 *digest_value,
return ret;
}

/*
* Calculate the memory required for serializing a single
* binary_runtime_measurement list entry, which contains a
* couple of variable length fields (e.g template name and data).
*/
static int get_binary_runtime_size(struct ima_template_entry *entry)
{
int size = 0;

size += sizeof(u32); /* pcr */
size += sizeof(entry->digest);
size += sizeof(int); /* template name size field */
size += strlen(entry->template_desc->name) + 1;
size += sizeof(entry->template_data_len);
size += entry->template_data_len;
return size;
}

/* ima_add_template_entry helper function:
* - Add template entry to the measurement list and hash table, for
* all entries except those carried across kexec.
Expand Down Expand Up @@ -91,9 +114,30 @@ static int ima_add_digest_entry(struct ima_template_entry *entry,
key = ima_hash_key(entry->digest);
hlist_add_head_rcu(&qe->hnext, &ima_htable.queue[key]);
}

if (binary_runtime_size != ULONG_MAX) {
int size;

size = get_binary_runtime_size(entry);
binary_runtime_size = (binary_runtime_size < ULONG_MAX - size) ?
binary_runtime_size + size : ULONG_MAX;
}
return 0;
}

/*
* Return the amount of memory required for serializing the
* entire binary_runtime_measurement list, including the ima_kexec_hdr
* structure.
*/
unsigned long ima_get_binary_runtime_size(void)
{
if (binary_runtime_size >= (ULONG_MAX - sizeof(struct ima_kexec_hdr)))
return ULONG_MAX;
else
return binary_runtime_size + sizeof(struct ima_kexec_hdr);
};

static int ima_pcr_extend(const u8 *hash, int pcr)
{
int result = 0;
Expand All @@ -107,8 +151,13 @@ static int ima_pcr_extend(const u8 *hash, int pcr)
return result;
}

/* Add template entry to the measurement list and hash table,
* and extend the pcr.
/*
* Add template entry to the measurement list and hash table, and
* extend the pcr.
*
* On systems which support carrying the IMA measurement list across
* kexec, maintain the total memory size required for serializing the
* binary_runtime_measurements.
*/
int ima_add_template_entry(struct ima_template_entry *entry, int violation,
const char *op, struct inode *inode,
Expand Down

0 comments on commit d158847

Please sign in to comment.