security/integrity/ima/ima_fs.c

Source file repositories/reference/linux-study-clean/security/integrity/ima/ima_fs.c

File Facts

System
Linux kernel
Corpus path
security/integrity/ima/ima_fs.c
Extension
.c
Size
20780 bytes
Lines
850
Domain
Core OS
Bucket
Security And Isolation
Inferred role
Core OS: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations ima_num_violations_ops = {
	.read = ima_show_num_violations,
	.llseek = generic_file_llseek,
};

static ssize_t ima_show_measurements_count(struct file *filp,
					   char __user *buf,
					   size_t count, loff_t *ppos)
{
	return ima_show_counter(buf, count, ppos, &ima_num_records[BINARY]);
}

static const struct file_operations ima_measurements_count_ops = {
	.read = ima_show_measurements_count,
	.llseek = generic_file_llseek,
};

/* returns pointer to hlist_node */
static void *_ima_measurements_start(struct seq_file *m, loff_t *pos,
				     struct list_head *head)
{
	loff_t l = *pos;
	struct ima_queue_entry *qe;

	/* we need a lock since pos could point beyond last element */
	rcu_read_lock();
	list_for_each_entry_rcu(qe, head, later) {
		if (!l--) {
			rcu_read_unlock();
			return qe;
		}
	}
	rcu_read_unlock();
	return NULL;
}

static void *ima_measurements_start(struct seq_file *m, loff_t *pos)
{
	return _ima_measurements_start(m, pos, &ima_measurements);
}

static void *ima_measurements_staged_start(struct seq_file *m, loff_t *pos)
{
	return _ima_measurements_start(m, pos, &ima_measurements_staged);
}

static void *_ima_measurements_next(struct seq_file *m, void *v, loff_t *pos,
				    struct list_head *head)
{
	struct ima_queue_entry *qe = v;

	/* lock protects when reading beyond last element
	 * against concurrent list-extension
	 */
	rcu_read_lock();
	qe = list_entry_rcu(qe->later.next, struct ima_queue_entry, later);
	rcu_read_unlock();
	(*pos)++;

	return (&qe->later == head) ? NULL : qe;
}

static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos)
{
	return _ima_measurements_next(m, v, pos, &ima_measurements);
}

static void *ima_measurements_staged_next(struct seq_file *m, void *v,
					  loff_t *pos)
{
	return _ima_measurements_next(m, v, pos, &ima_measurements_staged);
}

static void ima_measurements_stop(struct seq_file *m, void *v)
{
}

void ima_putc(struct seq_file *m, void *data, int datalen)
{
	while (datalen--)
		seq_putc(m, *(char *)data++);
}

/* print format:
 *       32bit-le=pcr#
 *       char[n]=template digest
 *       32bit-le=template name size
 *       char[n]=template name
 *       [eventdata length]
 *       eventdata[n]=template specific data

Annotation

Implementation Notes