]>
git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - security/integrity/ima/ima_api.c
2 * Copyright (C) 2008 IBM Corporation
4 * Author: Mimi Zohar <zohar@us.ibm.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2 of the
12 * Implements must_appraise_or_measure, collect_measurement,
13 * appraise_measurement, store_measurement and store_template.
15 #include <linux/module.h>
16 #include <linux/slab.h>
17 #include <linux/file.h>
19 #include <linux/xattr.h>
20 #include <linux/evm.h>
21 #include <crypto/hash_info.h>
24 static const char *IMA_TEMPLATE_NAME
= "ima";
27 * ima_store_template - store ima template measurements
29 * Calculate the hash of a template entry, add the template entry
30 * to an ordered list of measurement entries maintained inside the kernel,
31 * and also update the aggregate integrity value (maintained inside the
32 * configured TPM PCR) over the hashes of the current list of measurement
35 * Applications retrieve the current kernel-held measurement list through
36 * the securityfs entries in /sys/kernel/security/ima. The signed aggregate
37 * TPM PCR (called quote) can be retrieved using a TPM user space library
38 * and is used to validate the measurement list.
40 * Returns 0 on success, error code otherwise
42 int ima_store_template(struct ima_template_entry
*entry
,
43 int violation
, struct inode
*inode
)
45 const char *op
= "add_template_measure";
46 const char *audit_cause
= "hashing_error";
49 struct ima_digest_data hdr
;
50 char digest
[TPM_DIGEST_SIZE
];
53 memset(entry
->digest
, 0, sizeof(entry
->digest
));
54 entry
->template_name
= IMA_TEMPLATE_NAME
;
55 entry
->template_len
= sizeof(entry
->template);
58 /* this function uses default algo */
59 hash
.hdr
.algo
= HASH_ALGO_SHA1
;
60 result
= ima_calc_buffer_hash(&entry
->template,
61 entry
->template_len
, &hash
.hdr
);
63 integrity_audit_msg(AUDIT_INTEGRITY_PCR
, inode
,
64 entry
->template_name
, op
,
65 audit_cause
, result
, 0);
68 memcpy(entry
->digest
, hash
.hdr
.digest
, hash
.hdr
.length
);
70 result
= ima_add_template_entry(entry
, violation
, op
, inode
);
75 * ima_add_violation - add violation to measurement list.
77 * Violations are flagged in the measurement list with zero hash values.
78 * By extending the PCR with 0xFF's instead of with zeroes, the PCR
79 * value is invalidated.
81 void ima_add_violation(struct file
*file
, const unsigned char *filename
,
82 const char *op
, const char *cause
)
84 struct ima_template_entry
*entry
;
85 struct inode
*inode
= file
->f_dentry
->d_inode
;
89 /* can overflow, only indicator */
90 atomic_long_inc(&ima_htable
.violations
);
92 entry
= kmalloc(sizeof(*entry
), GFP_KERNEL
);
97 memset(&entry
->template, 0, sizeof(entry
->template));
98 strncpy(entry
->template.file_name
, filename
, IMA_EVENT_NAME_LEN_MAX
);
99 result
= ima_store_template(entry
, violation
, inode
);
103 integrity_audit_msg(AUDIT_INTEGRITY_PCR
, inode
, filename
,
104 op
, cause
, result
, 0);
108 * ima_get_action - appraise & measure decision based on policy.
109 * @inode: pointer to inode to measure
110 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
111 * @function: calling function (FILE_CHECK, BPRM_CHECK, MMAP_CHECK, MODULE_CHECK)
113 * The policy is defined in terms of keypairs:
114 * subj=, obj=, type=, func=, mask=, fsmagic=
115 * subj,obj, and type: are LSM specific.
116 * func: FILE_CHECK | BPRM_CHECK | MMAP_CHECK | MODULE_CHECK
117 * mask: contains the permission mask
120 * Returns IMA_MEASURE, IMA_APPRAISE mask.
123 int ima_get_action(struct inode
*inode
, int mask
, int function
)
125 int flags
= IMA_MEASURE
| IMA_AUDIT
| IMA_APPRAISE
;
128 flags
&= ~IMA_APPRAISE
;
130 return ima_match_policy(inode
, function
, mask
, flags
);
133 int ima_must_measure(struct inode
*inode
, int mask
, int function
)
135 return ima_match_policy(inode
, function
, mask
, IMA_MEASURE
);
139 * ima_collect_measurement - collect file measurement
141 * Calculate the file hash, if it doesn't already exist,
142 * storing the measurement and i_version in the iint.
144 * Must be called with iint->mutex held.
146 * Return 0 on success, error code otherwise
148 int ima_collect_measurement(struct integrity_iint_cache
*iint
,
150 struct evm_ima_xattr_data
**xattr_value
,
153 struct inode
*inode
= file_inode(file
);
154 const char *filename
= file
->f_dentry
->d_name
.name
;
157 struct ima_digest_data hdr
;
158 char digest
[IMA_MAX_DIGEST_SIZE
];
162 *xattr_len
= ima_read_xattr(file
->f_dentry
, xattr_value
);
164 if (!(iint
->flags
& IMA_COLLECTED
)) {
165 u64 i_version
= file_inode(file
)->i_version
;
167 /* use default hash algorithm */
168 hash
.hdr
.algo
= ima_hash_algo
;
171 ima_get_hash_algo(*xattr_value
, *xattr_len
, &hash
.hdr
);
173 result
= ima_calc_file_hash(file
, &hash
.hdr
);
175 int length
= sizeof(hash
.hdr
) + hash
.hdr
.length
;
176 void *tmpbuf
= krealloc(iint
->ima_hash
, length
,
179 iint
->ima_hash
= tmpbuf
;
180 memcpy(iint
->ima_hash
, &hash
, length
);
181 iint
->version
= i_version
;
182 iint
->flags
|= IMA_COLLECTED
;
188 integrity_audit_msg(AUDIT_INTEGRITY_DATA
, inode
,
189 filename
, "collect_data", "failed",
195 * ima_store_measurement - store file measurement
197 * Create an "ima" template and then store the template by calling
198 * ima_store_template.
200 * We only get here if the inode has not already been measured,
201 * but the measurement could already exist:
202 * - multiple copies of the same file on either the same or
203 * different filesystems.
204 * - the inode was previously flushed as well as the iint info,
205 * containing the hashing info.
207 * Must be called with iint->mutex held.
209 void ima_store_measurement(struct integrity_iint_cache
*iint
,
210 struct file
*file
, const unsigned char *filename
)
212 const char *op
= "add_template_measure";
213 const char *audit_cause
= "ENOMEM";
214 int result
= -ENOMEM
;
215 struct inode
*inode
= file_inode(file
);
216 struct ima_template_entry
*entry
;
219 if (iint
->flags
& IMA_MEASURED
)
222 entry
= kmalloc(sizeof(*entry
), GFP_KERNEL
);
224 integrity_audit_msg(AUDIT_INTEGRITY_PCR
, inode
, filename
,
225 op
, audit_cause
, result
, 0);
228 memset(&entry
->template, 0, sizeof(entry
->template));
229 if (iint
->ima_hash
->algo
!= ima_hash_algo
) {
231 struct ima_digest_data hdr
;
232 char digest
[IMA_MAX_DIGEST_SIZE
];
235 hash
.hdr
.algo
= ima_hash_algo
;
236 result
= ima_calc_file_hash(file
, &hash
.hdr
);
238 integrity_audit_msg(AUDIT_INTEGRITY_DATA
, inode
,
239 filename
, "collect_data", "failed",
242 memcpy(entry
->template.digest
, hash
.hdr
.digest
,
245 memcpy(entry
->template.digest
, iint
->ima_hash
->digest
,
246 iint
->ima_hash
->length
);
247 strcpy(entry
->template.file_name
,
248 (strlen(filename
) > IMA_EVENT_NAME_LEN_MAX
) ?
249 file
->f_dentry
->d_name
.name
: filename
);
251 result
= ima_store_template(entry
, violation
, inode
);
252 if (!result
|| result
== -EEXIST
)
253 iint
->flags
|= IMA_MEASURED
;
258 void ima_audit_measurement(struct integrity_iint_cache
*iint
,
259 const unsigned char *filename
)
261 struct audit_buffer
*ab
;
262 char hash
[(iint
->ima_hash
->length
* 2) + 1];
265 if (iint
->flags
& IMA_AUDITED
)
268 for (i
= 0; i
< iint
->ima_hash
->length
; i
++)
269 hex_byte_pack(hash
+ (i
* 2), iint
->ima_hash
->digest
[i
]);
272 ab
= audit_log_start(current
->audit_context
, GFP_KERNEL
,
273 AUDIT_INTEGRITY_RULE
);
277 audit_log_format(ab
, "file=");
278 audit_log_untrustedstring(ab
, filename
);
279 audit_log_format(ab
, " hash=");
280 audit_log_untrustedstring(ab
, hash
);
282 audit_log_task_info(ab
, current
);
285 iint
->flags
|= IMA_AUDITED
;
288 const char *ima_d_path(struct path
*path
, char **pathbuf
)
290 char *pathname
= NULL
;
292 /* We will allow 11 spaces for ' (deleted)' to be appended */
293 *pathbuf
= kmalloc(PATH_MAX
+ 11, GFP_KERNEL
);
295 pathname
= d_path(path
, *pathbuf
, PATH_MAX
+ 11);
296 if (IS_ERR(pathname
)) {