diff options
author | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2016-12-19 19:22:42 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-20 12:48:44 -0500 |
commit | d158847ae89a25615f3d8757ad8c6f50fc816db5 (patch) | |
tree | 05a45b14b6d74a2e56492c49590849703c043dac | |
parent | dcfc56937b62bf720f99a4d9aabfd243194322be (diff) |
ima: maintain memory size needed for serializing the measurement list
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>
-rw-r--r-- | security/integrity/ima/Kconfig | 12 | ||||
-rw-r--r-- | security/integrity/ima/ima.h | 1 | ||||
-rw-r--r-- | security/integrity/ima/ima_queue.c | 53 |
3 files changed, 64 insertions, 2 deletions
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 5487827fa86c..370eb2f4dd37 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig | |||
@@ -27,6 +27,18 @@ config IMA | |||
27 | to learn more about IMA. | 27 | to learn more about IMA. |
28 | If unsure, say N. | 28 | If unsure, say N. |
29 | 29 | ||
30 | config IMA_KEXEC | ||
31 | bool "Enable carrying the IMA measurement list across a soft boot" | ||
32 | depends on IMA && TCG_TPM && HAVE_IMA_KEXEC | ||
33 | default n | ||
34 | help | ||
35 | TPM PCRs are only reset on a hard reboot. In order to validate | ||
36 | a TPM's quote after a soft boot, the IMA measurement list of the | ||
37 | running kernel must be saved and restored on boot. | ||
38 | |||
39 | Depending on the IMA policy, the measurement list can grow to | ||
40 | be very large. | ||
41 | |||
30 | config IMA_MEASURE_PCR_IDX | 42 | config IMA_MEASURE_PCR_IDX |
31 | int | 43 | int |
32 | depends on IMA | 44 | depends on IMA |
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 51dc8d57d64d..ea1dcc452911 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
@@ -143,6 +143,7 @@ void ima_print_digest(struct seq_file *m, u8 *digest, u32 size); | |||
143 | struct ima_template_desc *ima_template_desc_current(void); | 143 | struct ima_template_desc *ima_template_desc_current(void); |
144 | int ima_restore_measurement_entry(struct ima_template_entry *entry); | 144 | int ima_restore_measurement_entry(struct ima_template_entry *entry); |
145 | int ima_restore_measurement_list(loff_t bufsize, void *buf); | 145 | int ima_restore_measurement_list(loff_t bufsize, void *buf); |
146 | unsigned long ima_get_binary_runtime_size(void); | ||
146 | int ima_init_template(void); | 147 | int ima_init_template(void); |
147 | 148 | ||
148 | /* | 149 | /* |
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index e180de598a92..d9aa5ab71204 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c | |||
@@ -29,6 +29,11 @@ | |||
29 | #define AUDIT_CAUSE_LEN_MAX 32 | 29 | #define AUDIT_CAUSE_LEN_MAX 32 |
30 | 30 | ||
31 | LIST_HEAD(ima_measurements); /* list of all measurements */ | 31 | LIST_HEAD(ima_measurements); /* list of all measurements */ |
32 | #ifdef CONFIG_IMA_KEXEC | ||
33 | static unsigned long binary_runtime_size; | ||
34 | #else | ||
35 | static unsigned long binary_runtime_size = ULONG_MAX; | ||
36 | #endif | ||
32 | 37 | ||
33 | /* key: inode (before secure-hashing a file) */ | 38 | /* key: inode (before secure-hashing a file) */ |
34 | struct ima_h_table ima_htable = { | 39 | struct ima_h_table ima_htable = { |
@@ -64,6 +69,24 @@ static struct ima_queue_entry *ima_lookup_digest_entry(u8 *digest_value, | |||
64 | return ret; | 69 | return ret; |
65 | } | 70 | } |
66 | 71 | ||
72 | /* | ||
73 | * Calculate the memory required for serializing a single | ||
74 | * binary_runtime_measurement list entry, which contains a | ||
75 | * couple of variable length fields (e.g template name and data). | ||
76 | */ | ||
77 | static int get_binary_runtime_size(struct ima_template_entry *entry) | ||
78 | { | ||
79 | int size = 0; | ||
80 | |||
81 | size += sizeof(u32); /* pcr */ | ||
82 | size += sizeof(entry->digest); | ||
83 | size += sizeof(int); /* template name size field */ | ||
84 | size += strlen(entry->template_desc->name) + 1; | ||
85 | size += sizeof(entry->template_data_len); | ||
86 | size += entry->template_data_len; | ||
87 | return size; | ||
88 | } | ||
89 | |||
67 | /* ima_add_template_entry helper function: | 90 | /* ima_add_template_entry helper function: |
68 | * - Add template entry to the measurement list and hash table, for | 91 | * - Add template entry to the measurement list and hash table, for |
69 | * all entries except those carried across kexec. | 92 | * all entries except those carried across kexec. |
@@ -91,9 +114,30 @@ static int ima_add_digest_entry(struct ima_template_entry *entry, | |||
91 | key = ima_hash_key(entry->digest); | 114 | key = ima_hash_key(entry->digest); |
92 | hlist_add_head_rcu(&qe->hnext, &ima_htable.queue[key]); | 115 | hlist_add_head_rcu(&qe->hnext, &ima_htable.queue[key]); |
93 | } | 116 | } |
117 | |||
118 | if (binary_runtime_size != ULONG_MAX) { | ||
119 | int size; | ||
120 | |||
121 | size = get_binary_runtime_size(entry); | ||
122 | binary_runtime_size = (binary_runtime_size < ULONG_MAX - size) ? | ||
123 | binary_runtime_size + size : ULONG_MAX; | ||
124 | } | ||
94 | return 0; | 125 | return 0; |
95 | } | 126 | } |
96 | 127 | ||
128 | /* | ||
129 | * Return the amount of memory required for serializing the | ||
130 | * entire binary_runtime_measurement list, including the ima_kexec_hdr | ||
131 | * structure. | ||
132 | */ | ||
133 | unsigned long ima_get_binary_runtime_size(void) | ||
134 | { | ||
135 | if (binary_runtime_size >= (ULONG_MAX - sizeof(struct ima_kexec_hdr))) | ||
136 | return ULONG_MAX; | ||
137 | else | ||
138 | return binary_runtime_size + sizeof(struct ima_kexec_hdr); | ||
139 | }; | ||
140 | |||
97 | static int ima_pcr_extend(const u8 *hash, int pcr) | 141 | static int ima_pcr_extend(const u8 *hash, int pcr) |
98 | { | 142 | { |
99 | int result = 0; | 143 | int result = 0; |
@@ -107,8 +151,13 @@ static int ima_pcr_extend(const u8 *hash, int pcr) | |||
107 | return result; | 151 | return result; |
108 | } | 152 | } |
109 | 153 | ||
110 | /* Add template entry to the measurement list and hash table, | 154 | /* |
111 | * and extend the pcr. | 155 | * Add template entry to the measurement list and hash table, and |
156 | * extend the pcr. | ||
157 | * | ||
158 | * On systems which support carrying the IMA measurement list across | ||
159 | * kexec, maintain the total memory size required for serializing the | ||
160 | * binary_runtime_measurements. | ||
112 | */ | 161 | */ |
113 | int ima_add_template_entry(struct ima_template_entry *entry, int violation, | 162 | int ima_add_template_entry(struct ima_template_entry *entry, int violation, |
114 | const char *op, struct inode *inode, | 163 | const char *op, struct inode *inode, |