cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ima_fs.c (12873B)


      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[20]=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	int i;
    136
    137	/* get entry */
    138	e = qe->entry;
    139	if (e == NULL)
    140		return -1;
    141
    142	template_name = (e->template_desc->name[0] != '\0') ?
    143	    e->template_desc->name : e->template_desc->fmt;
    144
    145	/*
    146	 * 1st: PCRIndex
    147	 * PCR used defaults to the same (config option) in
    148	 * little-endian format, unless set in policy
    149	 */
    150	pcr = !ima_canonical_fmt ? e->pcr : (__force u32)cpu_to_le32(e->pcr);
    151	ima_putc(m, &pcr, sizeof(e->pcr));
    152
    153	/* 2nd: template digest */
    154	ima_putc(m, e->digests[ima_sha1_idx].digest, TPM_DIGEST_SIZE);
    155
    156	/* 3rd: template name size */
    157	namelen = !ima_canonical_fmt ? strlen(template_name) :
    158		(__force u32)cpu_to_le32(strlen(template_name));
    159	ima_putc(m, &namelen, sizeof(namelen));
    160
    161	/* 4th:  template name */
    162	ima_putc(m, template_name, strlen(template_name));
    163
    164	/* 5th:  template length (except for 'ima' template) */
    165	if (strcmp(template_name, IMA_TEMPLATE_IMA_NAME) == 0)
    166		is_ima_template = true;
    167
    168	if (!is_ima_template) {
    169		template_data_len = !ima_canonical_fmt ? e->template_data_len :
    170			(__force u32)cpu_to_le32(e->template_data_len);
    171		ima_putc(m, &template_data_len, sizeof(e->template_data_len));
    172	}
    173
    174	/* 6th:  template specific data */
    175	for (i = 0; i < e->template_desc->num_fields; i++) {
    176		enum ima_show_type show = IMA_SHOW_BINARY;
    177		const struct ima_template_field *field =
    178			e->template_desc->fields[i];
    179
    180		if (is_ima_template && strcmp(field->field_id, "d") == 0)
    181			show = IMA_SHOW_BINARY_NO_FIELD_LEN;
    182		if (is_ima_template && strcmp(field->field_id, "n") == 0)
    183			show = IMA_SHOW_BINARY_OLD_STRING_FMT;
    184		field->field_show(m, show, &e->template_data[i]);
    185	}
    186	return 0;
    187}
    188
    189static const struct seq_operations ima_measurments_seqops = {
    190	.start = ima_measurements_start,
    191	.next = ima_measurements_next,
    192	.stop = ima_measurements_stop,
    193	.show = ima_measurements_show
    194};
    195
    196static int ima_measurements_open(struct inode *inode, struct file *file)
    197{
    198	return seq_open(file, &ima_measurments_seqops);
    199}
    200
    201static const struct file_operations ima_measurements_ops = {
    202	.open = ima_measurements_open,
    203	.read = seq_read,
    204	.llseek = seq_lseek,
    205	.release = seq_release,
    206};
    207
    208void ima_print_digest(struct seq_file *m, u8 *digest, u32 size)
    209{
    210	u32 i;
    211
    212	for (i = 0; i < size; i++)
    213		seq_printf(m, "%02x", *(digest + i));
    214}
    215
    216/* print in ascii */
    217static int ima_ascii_measurements_show(struct seq_file *m, void *v)
    218{
    219	/* the list never shrinks, so we don't need a lock here */
    220	struct ima_queue_entry *qe = v;
    221	struct ima_template_entry *e;
    222	char *template_name;
    223	int i;
    224
    225	/* get entry */
    226	e = qe->entry;
    227	if (e == NULL)
    228		return -1;
    229
    230	template_name = (e->template_desc->name[0] != '\0') ?
    231	    e->template_desc->name : e->template_desc->fmt;
    232
    233	/* 1st: PCR used (config option) */
    234	seq_printf(m, "%2d ", e->pcr);
    235
    236	/* 2nd: SHA1 template hash */
    237	ima_print_digest(m, e->digests[ima_sha1_idx].digest, TPM_DIGEST_SIZE);
    238
    239	/* 3th:  template name */
    240	seq_printf(m, " %s", template_name);
    241
    242	/* 4th:  template specific data */
    243	for (i = 0; i < e->template_desc->num_fields; i++) {
    244		seq_puts(m, " ");
    245		if (e->template_data[i].len == 0)
    246			continue;
    247
    248		e->template_desc->fields[i]->field_show(m, IMA_SHOW_ASCII,
    249							&e->template_data[i]);
    250	}
    251	seq_puts(m, "\n");
    252	return 0;
    253}
    254
    255static const struct seq_operations ima_ascii_measurements_seqops = {
    256	.start = ima_measurements_start,
    257	.next = ima_measurements_next,
    258	.stop = ima_measurements_stop,
    259	.show = ima_ascii_measurements_show
    260};
    261
    262static int ima_ascii_measurements_open(struct inode *inode, struct file *file)
    263{
    264	return seq_open(file, &ima_ascii_measurements_seqops);
    265}
    266
    267static const struct file_operations ima_ascii_measurements_ops = {
    268	.open = ima_ascii_measurements_open,
    269	.read = seq_read,
    270	.llseek = seq_lseek,
    271	.release = seq_release,
    272};
    273
    274static ssize_t ima_read_policy(char *path)
    275{
    276	void *data = NULL;
    277	char *datap;
    278	size_t size;
    279	int rc, pathlen = strlen(path);
    280
    281	char *p;
    282
    283	/* remove \n */
    284	datap = path;
    285	strsep(&datap, "\n");
    286
    287	rc = kernel_read_file_from_path(path, 0, &data, INT_MAX, NULL,
    288					READING_POLICY);
    289	if (rc < 0) {
    290		pr_err("Unable to open file: %s (%d)", path, rc);
    291		return rc;
    292	}
    293	size = rc;
    294	rc = 0;
    295
    296	datap = data;
    297	while (size > 0 && (p = strsep(&datap, "\n"))) {
    298		pr_debug("rule: %s\n", p);
    299		rc = ima_parse_add_rule(p);
    300		if (rc < 0)
    301			break;
    302		size -= rc;
    303	}
    304
    305	vfree(data);
    306	if (rc < 0)
    307		return rc;
    308	else if (size)
    309		return -EINVAL;
    310	else
    311		return pathlen;
    312}
    313
    314static ssize_t ima_write_policy(struct file *file, const char __user *buf,
    315				size_t datalen, loff_t *ppos)
    316{
    317	char *data;
    318	ssize_t result;
    319
    320	if (datalen >= PAGE_SIZE)
    321		datalen = PAGE_SIZE - 1;
    322
    323	/* No partial writes. */
    324	result = -EINVAL;
    325	if (*ppos != 0)
    326		goto out;
    327
    328	data = memdup_user_nul(buf, datalen);
    329	if (IS_ERR(data)) {
    330		result = PTR_ERR(data);
    331		goto out;
    332	}
    333
    334	result = mutex_lock_interruptible(&ima_write_mutex);
    335	if (result < 0)
    336		goto out_free;
    337
    338	if (data[0] == '/') {
    339		result = ima_read_policy(data);
    340	} else if (ima_appraise & IMA_APPRAISE_POLICY) {
    341		pr_err("signed policy file (specified as an absolute pathname) required\n");
    342		integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
    343				    "policy_update", "signed policy required",
    344				    1, 0);
    345		result = -EACCES;
    346	} else {
    347		result = ima_parse_add_rule(data);
    348	}
    349	mutex_unlock(&ima_write_mutex);
    350out_free:
    351	kfree(data);
    352out:
    353	if (result < 0)
    354		valid_policy = 0;
    355
    356	return result;
    357}
    358
    359static struct dentry *ima_dir;
    360static struct dentry *ima_symlink;
    361static struct dentry *binary_runtime_measurements;
    362static struct dentry *ascii_runtime_measurements;
    363static struct dentry *runtime_measurements_count;
    364static struct dentry *violations;
    365static struct dentry *ima_policy;
    366
    367enum ima_fs_flags {
    368	IMA_FS_BUSY,
    369};
    370
    371static unsigned long ima_fs_flags;
    372
    373#ifdef	CONFIG_IMA_READ_POLICY
    374static const struct seq_operations ima_policy_seqops = {
    375		.start = ima_policy_start,
    376		.next = ima_policy_next,
    377		.stop = ima_policy_stop,
    378		.show = ima_policy_show,
    379};
    380#endif
    381
    382/*
    383 * ima_open_policy: sequentialize access to the policy file
    384 */
    385static int ima_open_policy(struct inode *inode, struct file *filp)
    386{
    387	if (!(filp->f_flags & O_WRONLY)) {
    388#ifndef	CONFIG_IMA_READ_POLICY
    389		return -EACCES;
    390#else
    391		if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
    392			return -EACCES;
    393		if (!capable(CAP_SYS_ADMIN))
    394			return -EPERM;
    395		return seq_open(filp, &ima_policy_seqops);
    396#endif
    397	}
    398	if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags))
    399		return -EBUSY;
    400	return 0;
    401}
    402
    403/*
    404 * ima_release_policy - start using the new measure policy rules.
    405 *
    406 * Initially, ima_measure points to the default policy rules, now
    407 * point to the new policy rules, and remove the securityfs policy file,
    408 * assuming a valid policy.
    409 */
    410static int ima_release_policy(struct inode *inode, struct file *file)
    411{
    412	const char *cause = valid_policy ? "completed" : "failed";
    413
    414	if ((file->f_flags & O_ACCMODE) == O_RDONLY)
    415		return seq_release(inode, file);
    416
    417	if (valid_policy && ima_check_policy() < 0) {
    418		cause = "failed";
    419		valid_policy = 0;
    420	}
    421
    422	pr_info("policy update %s\n", cause);
    423	integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
    424			    "policy_update", cause, !valid_policy, 0);
    425
    426	if (!valid_policy) {
    427		ima_delete_rules();
    428		valid_policy = 1;
    429		clear_bit(IMA_FS_BUSY, &ima_fs_flags);
    430		return 0;
    431	}
    432
    433	ima_update_policy();
    434#if !defined(CONFIG_IMA_WRITE_POLICY) && !defined(CONFIG_IMA_READ_POLICY)
    435	securityfs_remove(ima_policy);
    436	ima_policy = NULL;
    437#elif defined(CONFIG_IMA_WRITE_POLICY)
    438	clear_bit(IMA_FS_BUSY, &ima_fs_flags);
    439#elif defined(CONFIG_IMA_READ_POLICY)
    440	inode->i_mode &= ~S_IWUSR;
    441#endif
    442	return 0;
    443}
    444
    445static const struct file_operations ima_measure_policy_ops = {
    446	.open = ima_open_policy,
    447	.write = ima_write_policy,
    448	.read = seq_read,
    449	.release = ima_release_policy,
    450	.llseek = generic_file_llseek,
    451};
    452
    453int __init ima_fs_init(void)
    454{
    455	int ret;
    456
    457	ima_dir = securityfs_create_dir("ima", integrity_dir);
    458	if (IS_ERR(ima_dir))
    459		return PTR_ERR(ima_dir);
    460
    461	ima_symlink = securityfs_create_symlink("ima", NULL, "integrity/ima",
    462						NULL);
    463	if (IS_ERR(ima_symlink)) {
    464		ret = PTR_ERR(ima_symlink);
    465		goto out;
    466	}
    467
    468	binary_runtime_measurements =
    469	    securityfs_create_file("binary_runtime_measurements",
    470				   S_IRUSR | S_IRGRP, ima_dir, NULL,
    471				   &ima_measurements_ops);
    472	if (IS_ERR(binary_runtime_measurements)) {
    473		ret = PTR_ERR(binary_runtime_measurements);
    474		goto out;
    475	}
    476
    477	ascii_runtime_measurements =
    478	    securityfs_create_file("ascii_runtime_measurements",
    479				   S_IRUSR | S_IRGRP, ima_dir, NULL,
    480				   &ima_ascii_measurements_ops);
    481	if (IS_ERR(ascii_runtime_measurements)) {
    482		ret = PTR_ERR(ascii_runtime_measurements);
    483		goto out;
    484	}
    485
    486	runtime_measurements_count =
    487	    securityfs_create_file("runtime_measurements_count",
    488				   S_IRUSR | S_IRGRP, ima_dir, NULL,
    489				   &ima_measurements_count_ops);
    490	if (IS_ERR(runtime_measurements_count)) {
    491		ret = PTR_ERR(runtime_measurements_count);
    492		goto out;
    493	}
    494
    495	violations =
    496	    securityfs_create_file("violations", S_IRUSR | S_IRGRP,
    497				   ima_dir, NULL, &ima_htable_violations_ops);
    498	if (IS_ERR(violations)) {
    499		ret = PTR_ERR(violations);
    500		goto out;
    501	}
    502
    503	ima_policy = securityfs_create_file("policy", POLICY_FILE_FLAGS,
    504					    ima_dir, NULL,
    505					    &ima_measure_policy_ops);
    506	if (IS_ERR(ima_policy)) {
    507		ret = PTR_ERR(ima_policy);
    508		goto out;
    509	}
    510
    511	return 0;
    512out:
    513	securityfs_remove(ima_policy);
    514	securityfs_remove(violations);
    515	securityfs_remove(runtime_measurements_count);
    516	securityfs_remove(ascii_runtime_measurements);
    517	securityfs_remove(binary_runtime_measurements);
    518	securityfs_remove(ima_symlink);
    519	securityfs_remove(ima_dir);
    520
    521	return ret;
    522}