diff mbox series

[RFC,v2,3/4] ima: Create vpcr file on securityfs.

Message ID 20221031030000.298779-1-denis.semakin@huawei.com (mailing list archive)
State New, archived
Headers show
Series Virtualize PCR for Container-IMA | expand

Commit Message

Denis Semakin Oct. 31, 2022, 3 a.m. UTC
This file contains information of all virtual PCR registers
that is extended by kernel when the real PCR extension operation
is occurred.

It provides the values of cPCRs and PCR12 register.
During reading operation it calculates the final value of
of cPCRs, store it in temp_vpcr_hash structure.

Then this tempPCR value is used to extend the real PCR12 register.

E.g.:
$ sudo cat /sys/kernel/security/ima/vpcr
cPCR:  ab3c1c3ae0581168284738f01470d7be64b9a220bb4b7030b879ffc669a2e4b6
PCR12: 73b7267c1e9b74c573a6e243af1d574bf6141be162a51e6aef4cfc15c7550963

Signed-off-by: Denis Semakin <denis.semakin@huawei.com>
---
 security/integrity/ima/ima_fs.c | 72 +++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)
diff mbox series

Patch

diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index bb4c3d4493e2..d9e91b9f1564 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -25,6 +25,8 @@ 
 
 #include "ima.h"
 
+extern struct list_head vpcr_list;
+
 bool ima_canonical_fmt;
 static int __init default_canonical_fmt_setup(char *str)
 {
@@ -538,6 +540,65 @@  static const struct file_operations ima_active_ops = {
 	.write = ima_write_active,
 };
 
+static void *vpcr_start(struct seq_file *m, loff_t *pos)
+{
+	int err;
+
+	err = mutex_lock_interruptible(&vpcr_list_mutex);
+	if (err)
+		return ERR_PTR(err);
+
+	return seq_list_start(&vpcr_list, *pos);
+}
+
+static void *vpcr_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	return seq_list_next(v, &vpcr_list, pos);
+}
+
+static void vpcr_stop(struct seq_file *m, void *v)
+{
+	mutex_unlock(&vpcr_list_mutex);
+}
+
+static int vpcr_show(struct seq_file *m, void *v)
+{
+	struct vpcr_entry *vpcr = list_entry(v, struct vpcr_entry, list);
+
+	ima_putc(m, "cPCR: ", strlen("cPCR: "));
+	ima_putc(m, vpcr->vpcr_tmp, SHA256_DIGEST_SIZE);
+
+	return 0;
+}
+
+const struct seq_operations vpcr_seq_ops = {
+	.start = vpcr_start,
+	.next  = vpcr_next,
+	.stop  = vpcr_stop,
+	.show  = vpcr_show,
+};
+
+static int ima_vpcr_open(struct inode *inode, struct file *filp)
+{
+	struct user_namespace *user_ns = ima_user_ns_from_file(filp);
+	struct ima_namespace *ns = ima_ns_from_file(filp);
+
+	if (!ns->ima_tpm_chip)
+		return -ENODEV;
+
+	if (!ns_is_active(ns) || !mac_admin_ns_capable(user_ns))
+		return -EACCES;
+
+	return seq_open(filp, &vpcr_seq_ops);
+}
+
+static const struct file_operations ima_vpcr_fops = {
+	.open = ima_vpcr_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release,
+};
+
 int ima_fs_ns_init(struct user_namespace *user_ns, struct dentry *root)
 {
 	struct ima_namespace *ns = ima_ns_from_user_ns(user_ns);
@@ -549,6 +610,7 @@  int ima_fs_ns_init(struct user_namespace *user_ns, struct dentry *root)
 	struct dentry *runtime_measurements_count = NULL;
 	struct dentry *violations = NULL;
 	struct dentry *active = NULL;
+	struct dentry *vpcr = NULL;
 	int ret;
 
 	/*
@@ -625,6 +687,15 @@  int ima_fs_ns_init(struct user_namespace *user_ns, struct dentry *root)
 		goto out;
 	}
 
+	if (ns == &init_ima_ns) {
+		vpcr = securityfs_create_file("vpcr", S_IRUSR | S_IRGRP,
+					      ima_dir, NULL, &ima_vpcr_fops);
+		if (IS_ERR(vpcr)) {
+			ret = PTR_ERR(vpcr);
+			goto out;
+		}
+	}
+
 	if (!ns->ima_policy_removed) {
 		ns->ima_policy =
 		    securityfs_create_file("policy", POLICY_FILE_FLAGS,
@@ -652,6 +723,7 @@  int ima_fs_ns_init(struct user_namespace *user_ns, struct dentry *root)
 
 	return 0;
 out:
+	securityfs_remove(vpcr);
 	securityfs_remove(active);
 	securityfs_remove(ns->ima_policy);
 	securityfs_remove(violations);