Joel Stanley | a1fccbf | 2020-06-23 17:25:56 +0930 | [diff] [blame] | 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| 2 | From: Nayna Jain <nayna@linux.ibm.com> |
| 3 | Date: Wed, 30 Oct 2019 23:31:30 -0400 |
Joel Stanley | cb9bf57 | 2020-09-29 16:18:12 +0930 | [diff] [blame^] | 4 | Subject: [PATCH 06/19] ima: Make process_buffer_measurement() generic |
Joel Stanley | a1fccbf | 2020-06-23 17:25:56 +0930 | [diff] [blame] | 5 | |
| 6 | process_buffer_measurement() is limited to measuring the kexec boot |
| 7 | command line. This patch makes process_buffer_measurement() more |
| 8 | generic, allowing it to measure other types of buffer data (e.g. |
| 9 | blacklisted binary hashes or key hashes). |
| 10 | |
| 11 | process_buffer_measurement() may be called directly from an IMA hook |
| 12 | or as an auxiliary measurement record. In both cases the buffer |
| 13 | measurement is based on policy. This patch modifies the function to |
| 14 | conditionally retrieve the policy defined PCR and template for the IMA |
| 15 | hook case. |
| 16 | |
| 17 | Signed-off-by: Nayna Jain <nayna@linux.ibm.com> |
| 18 | [zohar@linux.ibm.com: added comment in process_buffer_measurement()] |
| 19 | Signed-off-by: Mimi Zohar <zohar@linux.ibm.com> |
| 20 | Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> |
| 21 | Link: https://lore.kernel.org/r/1572492694-6520-6-git-send-email-zohar@linux.ibm.com |
| 22 | (cherry picked from commit e14555e3d0e9edfad0a6840c0152f71aba97e793) |
| 23 | Signed-off-by: Joel Stanley <joel@jms.id.au> |
| 24 | --- |
| 25 | security/integrity/ima/ima.h | 3 ++ |
| 26 | security/integrity/ima/ima_main.c | 58 +++++++++++++++++++++---------- |
| 27 | 2 files changed, 43 insertions(+), 18 deletions(-) |
| 28 | |
| 29 | diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h |
Joel Stanley | cb9bf57 | 2020-09-29 16:18:12 +0930 | [diff] [blame^] | 30 | index 8173982e00ab..04800f7f2351 100644 |
Joel Stanley | a1fccbf | 2020-06-23 17:25:56 +0930 | [diff] [blame] | 31 | --- a/security/integrity/ima/ima.h |
| 32 | +++ b/security/integrity/ima/ima.h |
| 33 | @@ -219,6 +219,9 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, |
| 34 | struct evm_ima_xattr_data *xattr_value, |
| 35 | int xattr_len, const struct modsig *modsig, int pcr, |
| 36 | struct ima_template_desc *template_desc); |
| 37 | +void process_buffer_measurement(const void *buf, int size, |
| 38 | + const char *eventname, enum ima_hooks func, |
| 39 | + int pcr); |
| 40 | void ima_audit_measurement(struct integrity_iint_cache *iint, |
| 41 | const unsigned char *filename); |
| 42 | int ima_alloc_init_template(struct ima_event_data *event_data, |
| 43 | diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c |
| 44 | index a768f37a0a4d..bc730e553053 100644 |
| 45 | --- a/security/integrity/ima/ima_main.c |
| 46 | +++ b/security/integrity/ima/ima_main.c |
| 47 | @@ -626,14 +626,14 @@ int ima_load_data(enum kernel_load_data_id id) |
| 48 | * @buf: pointer to the buffer that needs to be added to the log. |
| 49 | * @size: size of buffer(in bytes). |
| 50 | * @eventname: event name to be used for the buffer entry. |
| 51 | - * @cred: a pointer to a credentials structure for user validation. |
| 52 | - * @secid: the secid of the task to be validated. |
| 53 | + * @func: IMA hook |
| 54 | + * @pcr: pcr to extend the measurement |
| 55 | * |
| 56 | * Based on policy, the buffer is measured into the ima log. |
| 57 | */ |
| 58 | -static void process_buffer_measurement(const void *buf, int size, |
| 59 | - const char *eventname, |
| 60 | - const struct cred *cred, u32 secid) |
| 61 | +void process_buffer_measurement(const void *buf, int size, |
| 62 | + const char *eventname, enum ima_hooks func, |
| 63 | + int pcr) |
| 64 | { |
| 65 | int ret = 0; |
| 66 | struct ima_template_entry *entry = NULL; |
| 67 | @@ -642,19 +642,45 @@ static void process_buffer_measurement(const void *buf, int size, |
| 68 | .filename = eventname, |
| 69 | .buf = buf, |
| 70 | .buf_len = size}; |
| 71 | - struct ima_template_desc *template_desc = NULL; |
| 72 | + struct ima_template_desc *template = NULL; |
| 73 | struct { |
| 74 | struct ima_digest_data hdr; |
| 75 | char digest[IMA_MAX_DIGEST_SIZE]; |
| 76 | } hash = {}; |
| 77 | int violation = 0; |
| 78 | - int pcr = CONFIG_IMA_MEASURE_PCR_IDX; |
| 79 | int action = 0; |
| 80 | + u32 secid; |
| 81 | |
| 82 | - action = ima_get_action(NULL, cred, secid, 0, KEXEC_CMDLINE, &pcr, |
| 83 | - &template_desc); |
| 84 | - if (!(action & IMA_MEASURE)) |
| 85 | - return; |
| 86 | + /* |
| 87 | + * Both LSM hooks and auxilary based buffer measurements are |
| 88 | + * based on policy. To avoid code duplication, differentiate |
| 89 | + * between the LSM hooks and auxilary buffer measurements, |
| 90 | + * retrieving the policy rule information only for the LSM hook |
| 91 | + * buffer measurements. |
| 92 | + */ |
| 93 | + if (func) { |
| 94 | + security_task_getsecid(current, &secid); |
| 95 | + action = ima_get_action(NULL, current_cred(), secid, 0, func, |
| 96 | + &pcr, &template); |
| 97 | + if (!(action & IMA_MEASURE)) |
| 98 | + return; |
| 99 | + } |
| 100 | + |
| 101 | + if (!pcr) |
| 102 | + pcr = CONFIG_IMA_MEASURE_PCR_IDX; |
| 103 | + |
| 104 | + if (!template) { |
| 105 | + template = lookup_template_desc("ima-buf"); |
| 106 | + ret = template_desc_init_fields(template->fmt, |
| 107 | + &(template->fields), |
| 108 | + &(template->num_fields)); |
| 109 | + if (ret < 0) { |
| 110 | + pr_err("template %s init failed, result: %d\n", |
| 111 | + (strlen(template->name) ? |
| 112 | + template->name : template->fmt), ret); |
| 113 | + return; |
| 114 | + } |
| 115 | + } |
| 116 | |
| 117 | iint.ima_hash = &hash.hdr; |
| 118 | iint.ima_hash->algo = ima_hash_algo; |
| 119 | @@ -664,7 +690,7 @@ static void process_buffer_measurement(const void *buf, int size, |
| 120 | if (ret < 0) |
| 121 | goto out; |
| 122 | |
| 123 | - ret = ima_alloc_init_template(&event_data, &entry, template_desc); |
| 124 | + ret = ima_alloc_init_template(&event_data, &entry, template); |
| 125 | if (ret < 0) |
| 126 | goto out; |
| 127 | |
| 128 | @@ -686,13 +712,9 @@ static void process_buffer_measurement(const void *buf, int size, |
| 129 | */ |
| 130 | void ima_kexec_cmdline(const void *buf, int size) |
| 131 | { |
| 132 | - u32 secid; |
| 133 | - |
| 134 | - if (buf && size != 0) { |
| 135 | - security_task_getsecid(current, &secid); |
| 136 | + if (buf && size != 0) |
| 137 | process_buffer_measurement(buf, size, "kexec-cmdline", |
| 138 | - current_cred(), secid); |
| 139 | - } |
| 140 | + KEXEC_CMDLINE, 0); |
| 141 | } |
| 142 | |
| 143 | static int __init init_ima(void) |