Commit bcbc9b0cf6d8f340a1d166e414f4612b353f7a9b

Authored by Mimi Zohar
1 parent 42a20ba5c9

ima: extend the measurement list to include the file signature

This patch defines a new template called 'ima-sig', which includes
the file signature in the template data, in addition to the file's
digest and pathname.

A template is composed of a set of fields.  Associated with each
field is an initialization and display function.  This patch defines
a new template field called 'sig', the initialization function
ima_eventsig_init(), and the display function ima_show_template_sig().

This patch modifies the .field_init() function definition to include
the 'security.ima' extended attribute and length.

Changelog:
- remove unused code (Dmitry Kasatkin)
- avoid calling ima_write_template_field_data() unnecesarily (Roberto Sassu)
- rename DATA_FMT_SIG to DATA_FMT_HEX
- cleanup ima_eventsig_init() based on Roberto's comments

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>

Showing 8 changed files with 73 additions and 12 deletions Side-by-side Diff

security/integrity/ima/Kconfig
... ... @@ -63,6 +63,8 @@
63 63 bool "ima"
64 64 config IMA_NG_TEMPLATE
65 65 bool "ima-ng (default)"
  66 + config IMA_SIG_TEMPLATE
  67 + bool "ima-sig"
66 68 endchoice
67 69  
68 70 config IMA_DEFAULT_TEMPLATE
... ... @@ -70,6 +72,7 @@
70 72 depends on IMA
71 73 default "ima" if IMA_TEMPLATE
72 74 default "ima-ng" if IMA_NG_TEMPLATE
  75 + default "ima-sig" if IMA_SIG_TEMPLATE
73 76  
74 77 choice
75 78 prompt "Default integrity hash algorithm"
security/integrity/ima/ima.h
... ... @@ -59,7 +59,8 @@
59 59 const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN];
60 60 int (*field_init) (struct integrity_iint_cache *iint, struct file *file,
61 61 const unsigned char *filename,
62   - struct ima_field_data *field_data);
  62 + struct evm_ima_xattr_data *xattr_value,
  63 + int xattr_len, struct ima_field_data *field_data);
63 64 void (*field_show) (struct seq_file *m, enum ima_show_type show,
64 65 struct ima_field_data *field_data);
65 66 };
66 67  
... ... @@ -134,12 +135,15 @@
134 135 struct evm_ima_xattr_data **xattr_value,
135 136 int *xattr_len);
136 137 void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
137   - const unsigned char *filename);
  138 + const unsigned char *filename,
  139 + struct evm_ima_xattr_data *xattr_value,
  140 + int xattr_len);
138 141 void ima_audit_measurement(struct integrity_iint_cache *iint,
139 142 const unsigned char *filename);
140 143 int ima_alloc_init_template(struct integrity_iint_cache *iint,
141 144 struct file *file, const unsigned char *filename,
142   - struct ima_template_entry **entry);
  145 + struct evm_ima_xattr_data *xattr_value,
  146 + int xattr_len, struct ima_template_entry **entry);
143 147 int ima_store_template(struct ima_template_entry *entry, int violation,
144 148 struct inode *inode, const unsigned char *filename);
145 149 const char *ima_d_path(struct path *path, char **pathbuf);
security/integrity/ima/ima_api.c
... ... @@ -26,7 +26,8 @@
26 26 */
27 27 int ima_alloc_init_template(struct integrity_iint_cache *iint,
28 28 struct file *file, const unsigned char *filename,
29   - struct ima_template_entry **entry)
  29 + struct evm_ima_xattr_data *xattr_value,
  30 + int xattr_len, struct ima_template_entry **entry)
30 31 {
31 32 struct ima_template_desc *template_desc = ima_template_desc_current();
32 33 int i, result = 0;
... ... @@ -41,6 +42,7 @@
41 42 u32 len;
42 43  
43 44 result = field->field_init(iint, file, filename,
  45 + xattr_value, xattr_len,
44 46 &((*entry)->template_data[i]));
45 47 if (result != 0)
46 48 goto out;
... ... @@ -123,7 +125,8 @@
123 125 /* can overflow, only indicator */
124 126 atomic_long_inc(&ima_htable.violations);
125 127  
126   - result = ima_alloc_init_template(NULL, file, filename, &entry);
  128 + result = ima_alloc_init_template(NULL, file, filename,
  129 + NULL, 0, &entry);
127 130 if (result < 0) {
128 131 result = -ENOMEM;
129 132 goto err_out;
... ... @@ -239,7 +242,9 @@
239 242 * Must be called with iint->mutex held.
240 243 */
241 244 void ima_store_measurement(struct integrity_iint_cache *iint,
242   - struct file *file, const unsigned char *filename)
  245 + struct file *file, const unsigned char *filename,
  246 + struct evm_ima_xattr_data *xattr_value,
  247 + int xattr_len)
243 248 {
244 249 const char *op = "add_template_measure";
245 250 const char *audit_cause = "ENOMEM";
... ... @@ -251,7 +256,8 @@
251 256 if (iint->flags & IMA_MEASURED)
252 257 return;
253 258  
254   - result = ima_alloc_init_template(iint, file, filename, &entry);
  259 + result = ima_alloc_init_template(iint, file, filename,
  260 + xattr_value, xattr_len, &entry);
255 261 if (result < 0) {
256 262 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
257 263 op, audit_cause, result, 0);
security/integrity/ima/ima_init.c
... ... @@ -69,7 +69,7 @@
69 69 }
70 70  
71 71 result = ima_alloc_init_template(iint, NULL, boot_aggregate_name,
72   - &entry);
  72 + NULL, 0, &entry);
73 73 if (result < 0)
74 74 return;
75 75  
security/integrity/ima/ima_main.c
... ... @@ -225,7 +225,8 @@
225 225 pathname = (const char *)file->f_dentry->d_name.name;
226 226  
227 227 if (action & IMA_MEASURE)
228   - ima_store_measurement(iint, file, pathname);
  228 + ima_store_measurement(iint, file, pathname,
  229 + xattr_value, xattr_len);
229 230 if (action & IMA_APPRAISE_SUBMASK)
230 231 rc = ima_appraise_measurement(_func, iint, file, pathname,
231 232 xattr_value, xattr_len);
security/integrity/ima/ima_template.c
... ... @@ -20,6 +20,7 @@
20 20 static struct ima_template_desc defined_templates[] = {
21 21 {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT},
22 22 {.name = "ima-ng",.fmt = "d-ng|n-ng"},
  23 + {.name = "ima-sig",.fmt = "d-ng|n-ng|sig"},
23 24 };
24 25  
25 26 static struct ima_template_field supported_fields[] = {
... ... @@ -31,6 +32,8 @@
31 32 .field_show = ima_show_template_digest_ng},
32 33 {.field_id = "n-ng",.field_init = ima_eventname_ng_init,
33 34 .field_show = ima_show_template_string},
  35 + {.field_id = "sig",.field_init = ima_eventsig_init,
  36 + .field_show = ima_show_template_sig},
34 37 };
35 38  
36 39 static struct ima_template_desc *ima_template;
security/integrity/ima/ima_template_lib.c
... ... @@ -28,7 +28,8 @@
28 28 DATA_FMT_DIGEST = 0,
29 29 DATA_FMT_DIGEST_WITH_ALGO,
30 30 DATA_FMT_EVENT_NAME,
31   - DATA_FMT_STRING
  31 + DATA_FMT_STRING,
  32 + DATA_FMT_HEX
32 33 };
33 34  
34 35 static int ima_write_template_field_data(const void *data, const u32 datalen,
... ... @@ -90,6 +91,9 @@
90 91 buf_ptr += 2;
91 92 buflen -= buf_ptr - field_data->data;
92 93 case DATA_FMT_DIGEST:
  94 + case DATA_FMT_HEX:
  95 + if (!buflen)
  96 + break;
93 97 ima_print_digest(m, buf_ptr, buflen);
94 98 break;
95 99 case DATA_FMT_STRING:
... ... @@ -147,6 +151,12 @@
147 151 ima_show_template_field_data(m, show, DATA_FMT_STRING, field_data);
148 152 }
149 153  
  154 +void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
  155 + struct ima_field_data *field_data)
  156 +{
  157 + ima_show_template_field_data(m, show, DATA_FMT_HEX, field_data);
  158 +}
  159 +
150 160 static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo,
151 161 struct ima_field_data *field_data,
152 162 bool size_limit)
... ... @@ -190,6 +200,7 @@
190 200 */
191 201 int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
192 202 const unsigned char *filename,
  203 + struct evm_ima_xattr_data *xattr_value, int xattr_len,
193 204 struct ima_field_data *field_data)
194 205 {
195 206 struct {
... ... @@ -237,7 +248,8 @@
237 248 */
238 249 int ima_eventdigest_ng_init(struct integrity_iint_cache *iint,
239 250 struct file *file, const unsigned char *filename,
240   - struct ima_field_data *field_data)
  251 + struct evm_ima_xattr_data *xattr_value,
  252 + int xattr_len, struct ima_field_data *field_data)
241 253 {
242 254 u8 *cur_digest = NULL, hash_algo = HASH_ALGO__LAST;
243 255 u32 cur_digestsize = 0;
... ... @@ -295,6 +307,7 @@
295 307 */
296 308 int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file,
297 309 const unsigned char *filename,
  310 + struct evm_ima_xattr_data *xattr_value, int xattr_len,
298 311 struct ima_field_data *field_data)
299 312 {
300 313 return ima_eventname_init_common(iint, file, filename,
301 314  
... ... @@ -306,9 +319,30 @@
306 319 */
307 320 int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file,
308 321 const unsigned char *filename,
  322 + struct evm_ima_xattr_data *xattr_value, int xattr_len,
309 323 struct ima_field_data *field_data)
310 324 {
311 325 return ima_eventname_init_common(iint, file, filename,
312 326 field_data, false);
  327 +}
  328 +
  329 +/*
  330 + * ima_eventsig_init - include the file signature as part of the template data
  331 + */
  332 +int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file,
  333 + const unsigned char *filename,
  334 + struct evm_ima_xattr_data *xattr_value, int xattr_len,
  335 + struct ima_field_data *field_data)
  336 +{
  337 + enum data_formats fmt = DATA_FMT_HEX;
  338 + int rc = 0;
  339 +
  340 + if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG))
  341 + goto out;
  342 +
  343 + rc = ima_write_template_field_data(xattr_value, xattr_len, fmt,
  344 + field_data);
  345 +out:
  346 + return rc;
313 347 }
security/integrity/ima/ima_template_lib.h
... ... @@ -24,17 +24,27 @@
24 24 struct ima_field_data *field_data);
25 25 void ima_show_template_string(struct seq_file *m, enum ima_show_type show,
26 26 struct ima_field_data *field_data);
  27 +void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
  28 + struct ima_field_data *field_data);
27 29 int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
28 30 const unsigned char *filename,
  31 + struct evm_ima_xattr_data *xattr_value, int xattr_len,
29 32 struct ima_field_data *field_data);
30 33 int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file,
31 34 const unsigned char *filename,
  35 + struct evm_ima_xattr_data *xattr_value, int xattr_len,
32 36 struct ima_field_data *field_data);
33 37 int ima_eventdigest_ng_init(struct integrity_iint_cache *iint,
34 38 struct file *file, const unsigned char *filename,
35   - struct ima_field_data *field_data);
  39 + struct evm_ima_xattr_data *xattr_value,
  40 + int xattr_len, struct ima_field_data *field_data);
36 41 int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file,
37 42 const unsigned char *filename,
  43 + struct evm_ima_xattr_data *xattr_value, int xattr_len,
38 44 struct ima_field_data *field_data);
  45 +int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file,
  46 + const unsigned char *filename,
  47 + struct evm_ima_xattr_data *xattr_value, int xattr_len,
  48 + struct ima_field_data *field_data);
39 49 #endif /* __LINUX_IMA_TEMPLATE_LIB_H */