File Index
Files and directories
Sign in
FILE

ima_fs.c

File preview with syntax highlighting.

linux-6.19.14/security/integrity/ima/ima_fs.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (C) 2005,2006,2007,2008 IBM Corporation
  4 *
  5 * Authors:
  6 * Kylene Hall <kjhall@us.ibm.com>
  7 * Reiner Sailer <sailer@us.ibm.com>
  8 * Mimi Zohar <zohar@us.ibm.com>
  9 *
 10 * File: ima_fs.c
 11 *	implemenents security file system for reporting
 12 *	current measurement list and IMA statistics
 13 */
 14
 15#include <linux/fcntl.h>
 16#include <linux/kernel_read_file.h>
 17#include <linux/slab.h>
 18#include <linux/init.h>
 19#include <linux/seq_file.h>
 20#include <linux/rculist.h>
 21#include <linux/rcupdate.h>
 22#include <linux/parser.h>
 23#include <linux/vmalloc.h>
 24
 25#include "ima.h"
 26
 27static DEFINE_MUTEX(ima_write_mutex);
 28
 29bool ima_canonical_fmt;
 30static int __init default_canonical_fmt_setup(char *str)
 31{
 32#ifdef __BIG_ENDIAN
 33	ima_canonical_fmt = true;
 34#endif
 35	return 1;
 36}
 37__setup("ima_canonical_fmt", default_canonical_fmt_setup);
 38
 39static int valid_policy = 1;
 40
 41static ssize_t ima_show_htable_value(char __user *buf, size_t count,
 42				     loff_t *ppos, atomic_long_t *val)
 43{
 44	char tmpbuf[32];	/* greater than largest 'long' string value */
 45	ssize_t len;
 46
 47	len = scnprintf(tmpbuf, sizeof(tmpbuf), "%li\n", atomic_long_read(val));
 48	return simple_read_from_buffer(buf, count, ppos, tmpbuf, len);
 49}
 50
 51static ssize_t ima_show_htable_violations(struct file *filp,
 52					  char __user *buf,
 53					  size_t count, loff_t *ppos)
 54{
 55	return ima_show_htable_value(buf, count, ppos, &ima_htable.violations);
 56}
 57
 58static const struct file_operations ima_htable_violations_ops = {
 59	.read = ima_show_htable_violations,
 60	.llseek = generic_file_llseek,
 61};
 62
 63static ssize_t ima_show_measurements_count(struct file *filp,
 64					   char __user *buf,
 65					   size_t count, loff_t *ppos)
 66{
 67	return ima_show_htable_value(buf, count, ppos, &ima_htable.len);
 68
 69}
 70
 71static const struct file_operations ima_measurements_count_ops = {
 72	.read = ima_show_measurements_count,
 73	.llseek = generic_file_llseek,
 74};
 75
 76/* returns pointer to hlist_node */
 77static void *ima_measurements_start(struct seq_file *m, loff_t *pos)
 78{
 79	loff_t l = *pos;
 80	struct ima_queue_entry *qe;
 81
 82	/* we need a lock since pos could point beyond last element */
 83	rcu_read_lock();
 84	list_for_each_entry_rcu(qe, &ima_measurements, later) {
 85		if (!l--) {
 86			rcu_read_unlock();
 87			return qe;
 88		}
 89	}
 90	rcu_read_unlock();
 91	return NULL;
 92}
 93
 94static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos)
 95{
 96	struct ima_queue_entry *qe = v;
 97
 98	/* lock protects when reading beyond last element
 99	 * against concurrent list-extension
100	 */
101	rcu_read_lock();
102	qe = list_entry_rcu(qe->later.next, struct ima_queue_entry, later);
103	rcu_read_unlock();
104	(*pos)++;
105
106	return (&qe->later == &ima_measurements) ? NULL : qe;
107}
108
109static void ima_measurements_stop(struct seq_file *m, void *v)
110{
111}
112
113void ima_putc(struct seq_file *m, void *data, int datalen)
114{
115	while (datalen--)
116		seq_putc(m, *(char *)data++);
117}
118
119/* print format:
120 *       32bit-le=pcr#
121 *       char[n]=template digest
122 *       32bit-le=template name size
123 *       char[n]=template name
124 *       [eventdata length]
125 *       eventdata[n]=template specific data
126 */
127int ima_measurements_show(struct seq_file *m, void *v)
128{
129	/* the list never shrinks, so we don't need a lock here */
130	struct ima_queue_entry *qe = v;
131	struct ima_template_entry *e;
132	char *template_name;
133	u32 pcr, namelen, template_data_len; /* temporary fields */
134	bool is_ima_template = false;
135	enum hash_algo algo;
136	int i, algo_idx;
137
138	algo_idx = ima_sha1_idx;
139	algo = HASH_ALGO_SHA1;
140
141	if (m->file != NULL) {
142		algo_idx = (unsigned long)file_inode(m->file)->i_private;
143		algo = ima_algo_array[algo_idx].algo;
144	}
145
146	/* get entry */
147	e = qe->entry;
148	if (e == NULL)
149		return -1;
150
151	template_name = (e->template_desc->name[0] != '\0') ?
152	    e->template_desc->name : e->template_desc->fmt;
153
154	/*
155	 * 1st: PCRIndex
156	 * PCR used defaults to the same (config option) in
157	 * little-endian format, unless set in policy
158	 */
159	pcr = !ima_canonical_fmt ? e->pcr : (__force u32)cpu_to_le32(e->pcr);
160	ima_putc(m, &pcr, sizeof(e->pcr));
161
162	/* 2nd: template digest */
163	ima_putc(m, e->digests[algo_idx].digest, hash_digest_size[algo]);
164
165	/* 3rd: template name size */
166	namelen = !ima_canonical_fmt ? strlen(template_name) :
167		(__force u32)cpu_to_le32(strlen(template_name));
168	ima_putc(m, &namelen, sizeof(namelen));
169
170	/* 4th:  template name */
171	ima_putc(m, template_name, strlen(template_name));
172
173	/* 5th:  template length (except for 'ima' template) */
174	if (strcmp(template_name, IMA_TEMPLATE_IMA_NAME) == 0)
175		is_ima_template = true;
176
177	if (!is_ima_template) {
178		template_data_len = !ima_canonical_fmt ? e->template_data_len :
179			(__force u32)cpu_to_le32(e->template_data_len);
180		ima_putc(m, &template_data_len, sizeof(e->template_data_len));
181	}
182
183	/* 6th:  template specific data */
184	for (i = 0; i < e->template_desc->num_fields; i++) {
185		enum ima_show_type show = IMA_SHOW_BINARY;
186		const struct ima_template_field *field =
187			e->template_desc->fields[i];
188
189		if (is_ima_template && strcmp(field->field_id, "d") == 0)
190			show = IMA_SHOW_BINARY_NO_FIELD_LEN;
191		if (is_ima_template && strcmp(field->field_id, "n") == 0)
192			show = IMA_SHOW_BINARY_OLD_STRING_FMT;
193		field->field_show(m, show, &e->template_data[i]);
194	}
195	return 0;
196}
197
198static const struct seq_operations ima_measurments_seqops = {
199	.start = ima_measurements_start,
200	.next = ima_measurements_next,
201	.stop = ima_measurements_stop,
202	.show = ima_measurements_show
203};
204
205static int ima_measurements_open(struct inode *inode, struct file *file)
206{
207	return seq_open(file, &ima_measurments_seqops);
208}
209
210static const struct file_operations ima_measurements_ops = {
211	.open = ima_measurements_open,
212	.read = seq_read,
213	.llseek = seq_lseek,
214	.release = seq_release,
215};
216
217void ima_print_digest(struct seq_file *m, u8 *digest, u32 size)
218{
219	u32 i;
220
221	for (i = 0; i < size; i++)
222		seq_printf(m, "%02x", *(digest + i));
223}
224
225/* print in ascii */
226static int ima_ascii_measurements_show(struct seq_file *m, void *v)
227{
228	/* the list never shrinks, so we don't need a lock here */
229	struct ima_queue_entry *qe = v;
230	struct ima_template_entry *e;
231	char *template_name;
232	enum hash_algo algo;
233	int i, algo_idx;
234
235	algo_idx = ima_sha1_idx;
236	algo = HASH_ALGO_SHA1;
237
238	if (m->file != NULL) {
239		algo_idx = (unsigned long)file_inode(m->file)->i_private;
240		algo = ima_algo_array[algo_idx].algo;
241	}
242
243	/* get entry */
244	e = qe->entry;
245	if (e == NULL)
246		return -1;
247
248	template_name = (e->template_desc->name[0] != '\0') ?
249	    e->template_desc->name : e->template_desc->fmt;
250
251	/* 1st: PCR used (config option) */
252	seq_printf(m, "%2d ", e->pcr);
253
254	/* 2nd: template hash */
255	ima_print_digest(m, e->digests[algo_idx].digest, hash_digest_size[algo]);
256
257	/* 3th:  template name */
258	seq_printf(m, " %s", template_name);
259
260	/* 4th:  template specific data */
261	for (i = 0; i < e->template_desc->num_fields; i++) {
262		seq_puts(m, " ");
263		if (e->template_data[i].len == 0)
264			continue;
265
266		e->template_desc->fields[i]->field_show(m, IMA_SHOW_ASCII,
267							&e->template_data[i]);
268	}
269	seq_puts(m, "\n");
270	return 0;
271}
272
273static const struct seq_operations ima_ascii_measurements_seqops = {
274	.start = ima_measurements_start,
275	.next = ima_measurements_next,
276	.stop = ima_measurements_stop,
277	.show = ima_ascii_measurements_show
278};
279
280static int ima_ascii_measurements_open(struct inode *inode, struct file *file)
281{
282	return seq_open(file, &ima_ascii_measurements_seqops);
283}
284
285static const struct file_operations ima_ascii_measurements_ops = {
286	.open = ima_ascii_measurements_open,
287	.read = seq_read,
288	.llseek = seq_lseek,
289	.release = seq_release,
290};
291
292static ssize_t ima_read_policy(char *path)
293{
294	void *data = NULL;
295	char *datap;
296	size_t size;
297	int rc, pathlen = strlen(path);
298
299	char *p;
300
301	/* remove \n */
302	datap = path;
303	strsep(&datap, "\n");
304
305	rc = kernel_read_file_from_path(path, 0, &data, INT_MAX, NULL,
306					READING_POLICY);
307	if (rc < 0) {
308		pr_err("Unable to open file: %s (%d)", path, rc);
309		return rc;
310	}
311	size = rc;
312	rc = 0;
313
314	datap = data;
315	while (size > 0 && (p = strsep(&datap, "\n"))) {
316		pr_debug("rule: %s\n", p);
317		rc = ima_parse_add_rule(p);
318		if (rc < 0)
319			break;
320		size -= rc;
321	}
322
323	vfree(data);
324	if (rc < 0)
325		return rc;
326	else if (size)
327		return -EINVAL;
328	else
329		return pathlen;
330}
331
332static ssize_t ima_write_policy(struct file *file, const char __user *buf,
333				size_t datalen, loff_t *ppos)
334{
335	char *data;
336	ssize_t result;
337
338	if (datalen >= PAGE_SIZE)
339		datalen = PAGE_SIZE - 1;
340
341	/* No partial writes. */
342	result = -EINVAL;
343	if (*ppos != 0)
344		goto out;
345
346	data = memdup_user_nul(buf, datalen);
347	if (IS_ERR(data)) {
348		result = PTR_ERR(data);
349		goto out;
350	}
351
352	result = mutex_lock_interruptible(&ima_write_mutex);
353	if (result < 0)
354		goto out_free;
355
356	if (data[0] == '/') {
357		result = ima_read_policy(data);
358	} else if (ima_appraise & IMA_APPRAISE_POLICY) {
359		pr_err("signed policy file (specified as an absolute pathname) required\n");
360		integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
361				    "policy_update", "signed policy required",
362				    1, 0);
363		result = -EACCES;
364	} else {
365		result = ima_parse_add_rule(data);
366	}
367	mutex_unlock(&ima_write_mutex);
368out_free:
369	kfree(data);
370out:
371	if (result < 0)
372		valid_policy = 0;
373
374	return result;
375}
376
377static struct dentry *ima_dir;
378static struct dentry *ima_symlink;
379
380enum ima_fs_flags {
381	IMA_FS_BUSY,
382};
383
384static unsigned long ima_fs_flags;
385
386#ifdef	CONFIG_IMA_READ_POLICY
387static const struct seq_operations ima_policy_seqops = {
388		.start = ima_policy_start,
389		.next = ima_policy_next,
390		.stop = ima_policy_stop,
391		.show = ima_policy_show,
392};
393#endif
394
395static int __init create_securityfs_measurement_lists(void)
396{
397	int count = NR_BANKS(ima_tpm_chip);
398
399	if (ima_sha1_idx >= NR_BANKS(ima_tpm_chip))
400		count++;
401
402	for (int i = 0; i < count; i++) {
403		u16 algo = ima_algo_array[i].algo;
404		char file_name[NAME_MAX + 1];
405		struct dentry *dentry;
406
407		sprintf(file_name, "ascii_runtime_measurements_%s",
408			hash_algo_name[algo]);
409		dentry = securityfs_create_file(file_name, S_IRUSR | S_IRGRP,
410						ima_dir, (void *)(uintptr_t)i,
411						&ima_ascii_measurements_ops);
412		if (IS_ERR(dentry))
413			return PTR_ERR(dentry);
414
415		sprintf(file_name, "binary_runtime_measurements_%s",
416			hash_algo_name[algo]);
417		dentry = securityfs_create_file(file_name, S_IRUSR | S_IRGRP,
418						ima_dir, (void *)(uintptr_t)i,
419						&ima_measurements_ops);
420		if (IS_ERR(dentry))
421			return PTR_ERR(dentry);
422	}
423
424	return 0;
425}
426
427/*
428 * ima_open_policy: sequentialize access to the policy file
429 */
430static int ima_open_policy(struct inode *inode, struct file *filp)
431{
432	if (!(filp->f_flags & O_WRONLY)) {
433#ifndef	CONFIG_IMA_READ_POLICY
434		return -EACCES;
435#else
436		if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
437			return -EACCES;
438		if (!capable(CAP_SYS_ADMIN))
439			return -EPERM;
440		return seq_open(filp, &ima_policy_seqops);
441#endif
442	}
443	if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags))
444		return -EBUSY;
445	return 0;
446}
447
448/*
449 * ima_release_policy - start using the new measure policy rules.
450 *
451 * Initially, ima_measure points to the default policy rules, now
452 * point to the new policy rules, and remove the securityfs policy file,
453 * assuming a valid policy.
454 */
455static int ima_release_policy(struct inode *inode, struct file *file)
456{
457	const char *cause = valid_policy ? "completed" : "failed";
458
459	if ((file->f_flags & O_ACCMODE) == O_RDONLY)
460		return seq_release(inode, file);
461
462	if (valid_policy && ima_check_policy() < 0) {
463		cause = "failed";
464		valid_policy = 0;
465	}
466
467	pr_info("policy update %s\n", cause);
468	integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
469			    "policy_update", cause, !valid_policy, 0);
470
471	if (!valid_policy) {
472		ima_delete_rules();
473		valid_policy = 1;
474		clear_bit(IMA_FS_BUSY, &ima_fs_flags);
475		return 0;
476	}
477
478	ima_update_policy();
479#if !defined(CONFIG_IMA_WRITE_POLICY) && !defined(CONFIG_IMA_READ_POLICY)
480	securityfs_remove(file->f_path.dentry);
481#elif defined(CONFIG_IMA_WRITE_POLICY)
482	clear_bit(IMA_FS_BUSY, &ima_fs_flags);
483#elif defined(CONFIG_IMA_READ_POLICY)
484	inode->i_mode &= ~S_IWUSR;
485#endif
486	return 0;
487}
488
489static const struct file_operations ima_measure_policy_ops = {
490	.open = ima_open_policy,
491	.write = ima_write_policy,
492	.read = seq_read,
493	.release = ima_release_policy,
494	.llseek = generic_file_llseek,
495};
496
497int __init ima_fs_init(void)
498{
499	struct dentry *dentry;
500	int ret;
501
502	ret = integrity_fs_init();
503	if (ret < 0)
504		return ret;
505
506	ima_dir = securityfs_create_dir("ima", integrity_dir);
507	if (IS_ERR(ima_dir)) {
508		ret = PTR_ERR(ima_dir);
509		goto out;
510	}
511
512	ima_symlink = securityfs_create_symlink("ima", NULL, "integrity/ima",
513						NULL);
514	if (IS_ERR(ima_symlink)) {
515		ret = PTR_ERR(ima_symlink);
516		goto out;
517	}
518
519	ret = create_securityfs_measurement_lists();
520	if (ret != 0)
521		goto out;
522
523	dentry = securityfs_create_symlink("binary_runtime_measurements", ima_dir,
524				      "binary_runtime_measurements_sha1", NULL);
525	if (IS_ERR(dentry)) {
526		ret = PTR_ERR(dentry);
527		goto out;
528	}
529
530	dentry = securityfs_create_symlink("ascii_runtime_measurements", ima_dir,
531				      "ascii_runtime_measurements_sha1", NULL);
532	if (IS_ERR(dentry)) {
533		ret = PTR_ERR(dentry);
534		goto out;
535	}
536
537	dentry = securityfs_create_file("runtime_measurements_count",
538				   S_IRUSR | S_IRGRP, ima_dir, NULL,
539				   &ima_measurements_count_ops);
540	if (IS_ERR(dentry)) {
541		ret = PTR_ERR(dentry);
542		goto out;
543	}
544
545	dentry = securityfs_create_file("violations", S_IRUSR | S_IRGRP,
546				   ima_dir, NULL, &ima_htable_violations_ops);
547	if (IS_ERR(dentry)) {
548		ret = PTR_ERR(dentry);
549		goto out;
550	}
551
552	dentry = securityfs_create_file("policy", POLICY_FILE_FLAGS,
553					    ima_dir, NULL,
554					    &ima_measure_policy_ops);
555	if (IS_ERR(dentry)) {
556		ret = PTR_ERR(dentry);
557		goto out;
558	}
559
560	return 0;
561out:
562	securityfs_remove(ima_symlink);
563	securityfs_remove(ima_dir);
564	integrity_fs_fini();
565
566	return ret;
567}
~/ Read-only file preview.