| 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) |