All of lore.kernel.org
 help / color / mirror / Atom feed
From: Roberto Sassu <roberto.sassu@huawei.com>
To: <zohar@linux.ibm.com>
Cc: <linux-integrity@vger.kernel.org>,
	<linux-security-module@vger.kernel.org>,
	<linux-doc@vger.kernel.org>, <linux-kselftest@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>,
	Roberto Sassu <roberto.sassu@huawei.com>
Subject: [RFC][PATCH 10/12] digest_lists: Interfaces - digest_query
Date: Fri, 25 Jun 2021 18:56:12 +0200	[thread overview]
Message-ID: <20210625165614.2284243-11-roberto.sassu@huawei.com> (raw)
In-Reply-To: <20210625165614.2284243-1-roberto.sassu@huawei.com>

This patch introduces the digest_query interface, which allows to write a
query in the format ``<algo>-<digest>`` and to obtain all digest lists that
include that digest.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 Documentation/security/digest_lists.rst |   7 ++
 security/integrity/digest_lists/fs.c    | 150 ++++++++++++++++++++++++
 2 files changed, 157 insertions(+)

diff --git a/Documentation/security/digest_lists.rst b/Documentation/security/digest_lists.rst
index d83279046a55..f3900a6e92f6 100644
--- a/Documentation/security/digest_lists.rst
+++ b/Documentation/security/digest_lists.rst
@@ -690,3 +690,10 @@ removed.
 
 ``digest_label`` can be used to set a label to be applied to the next
 digest list (buffer) loaded ``through digest_list_add``.
+
+
+``digest_query``
+~~~~~~~~~~~~~~~~
+
+``digest_query``: allows to write a query in the format ``<algo>-<digest>``
+and to obtain all digest lists that include that digest.
diff --git a/security/integrity/digest_lists/fs.c b/security/integrity/digest_lists/fs.c
index f6e88fac27bc..bdfeb8797760 100644
--- a/security/integrity/digest_lists/fs.c
+++ b/security/integrity/digest_lists/fs.c
@@ -31,12 +31,17 @@
 
 #define HDR_ASCII_FMT \
 	"actions: %d, version: %d, algo: %s, type: %d, modifiers: %d, count: %d, datalen: %d\n"
+#define QUERY_RESULT_FMT \
+	"%s (actions: %d): version: %d, algo: %s, type: %d, modifiers: %d, count: %d, datalen: %d\n"
+#define QUERY_RESULT_DIGEST_LIST_FMT "%s (actions: %d): type: %d, size: %lld\n"
 
 static struct dentry *digest_lists_dir;
 static struct dentry *digest_lists_loaded_dir;
 static struct dentry *digest_label_dentry;
+static struct dentry *digest_query_dentry;
 static struct dentry *digest_list_add_dentry;
 static struct dentry *digest_list_del_dentry;
+char digest_query[CRYPTO_MAX_ALG_NAME + 1 + IMA_MAX_DIGEST_SIZE * 2 + 1];
 char digest_label[NAME_MAX + 1];
 
 static int parse_digest_list_filename(const char *digest_list_filename,
@@ -224,6 +229,83 @@ static const struct file_operations digest_list_ascii_ops = {
 	.release = seq_release,
 };
 
+static void *digest_query_start(struct seq_file *m, loff_t *pos)
+{
+	struct digest_item *d;
+	u8 digest[IMA_MAX_DIGEST_SIZE];
+	enum hash_algo algo;
+	loff_t count = 0;
+	enum compact_types type = 0;
+	struct digest_list_item_ref *ref;
+	int ret, refs;
+
+	ret = parse_digest_list_filename(digest_query, digest, &algo);
+	if (ret < 0)
+		return NULL;
+
+	for (type = 0; type < COMPACT__LAST; type++) {
+		d = digest_lookup(digest, algo, type, NULL, NULL);
+		if (!d)
+			continue;
+
+		rcu_read_lock();
+		for (ref = rcu_dereference(d->refs), refs = 0;
+		     ref != NULL && !digest_list_ref_is_last(ref);
+		     ref++, refs++)
+			;
+		rcu_read_unlock();
+
+		count += refs;
+
+		if (count > *pos)
+			break;
+	}
+
+	if (type == COMPACT__LAST)
+		return NULL;
+
+	return d->refs ? d->refs + (*pos - (count - refs)) : NULL;
+}
+
+static void *digest_query_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	struct digest_list_item_ref *refs = (struct digest_list_item_ref *)v;
+
+	refs++;
+	(*pos)++;
+
+	return (refs->digest_list) ? refs : NULL;
+}
+
+static void digest_query_stop(struct seq_file *m, void *v)
+{
+}
+
+static int digest_query_show(struct seq_file *m, void *v)
+{
+	struct digest_list_item_ref *refs = (struct digest_list_item_ref *)v;
+	struct digest_list_item *digest_list = refs->digest_list;
+	struct compact_list_hdr *hdr;
+
+	if (digest_list_ref_invalidated(refs))
+		return 0;
+
+	hdr = get_hdr_ref(refs);
+
+	if (!refs->digest_offset) {
+		seq_printf(m, QUERY_RESULT_DIGEST_LIST_FMT, digest_list->label,
+			   digest_list->actions, COMPACT_DIGEST_LIST,
+			   digest_list->size);
+		return 0;
+	}
+
+	seq_printf(m, QUERY_RESULT_FMT, digest_list->label,
+		   digest_list->actions, hdr->version,
+		   hash_algo_name[hdr->algo], hdr->type, hdr->modifiers,
+		   hdr->count, hdr->datalen);
+	return 0;
+}
+
 static int digest_list_get_secfs_files(char *label, u8 *digest,
 				       enum hash_algo algo, enum ops op,
 				       struct dentry **dentry,
@@ -492,6 +574,67 @@ static const struct file_operations digest_label_ops = {
 	.llseek = generic_file_llseek,
 };
 
+static const struct seq_operations digest_query_seqops = {
+	.start = digest_query_start,
+	.next = digest_query_next,
+	.stop = digest_query_stop,
+	.show = digest_query_show,
+};
+
+/*
+ * digest_query_open: open to write a query or read the result.
+ */
+static int digest_query_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(0, &flags))
+		return -EBUSY;
+
+	if (file->f_flags & O_WRONLY)
+		return 0;
+
+	return seq_open(file, &digest_query_seqops);
+}
+
+/*
+ * digest_query_open: write digest query (<algo>-<digest>).
+ */
+static ssize_t digest_query_write(struct file *file, const char __user *buf,
+				  size_t datalen, loff_t *ppos)
+{
+	int rc;
+
+	if (datalen >= sizeof(digest_query))
+		return -EINVAL;
+
+	rc = copy_from_user(digest_query, buf, datalen);
+	if (rc < 0)
+		return rc;
+
+	digest_query[datalen] = '\0';
+	return datalen;
+}
+
+/*
+ * digest_query_release - release the digest_query file
+ */
+static int digest_query_release(struct inode *inode, struct file *file)
+{
+	clear_bit(0, &flags);
+
+	if (file->f_flags & O_WRONLY)
+		return 0;
+
+	return seq_release(inode, file);
+}
+
+static const struct file_operations digest_query_ops = {
+	.open = digest_query_open,
+	.write = digest_query_write,
+	.read = seq_read,
+	.release = digest_query_release,
+	.llseek = generic_file_llseek,
+};
+
 static int __init digest_lists_fs_init(void)
 {
 	digest_lists_dir = securityfs_create_dir("digest_lists", integrity_dir);
@@ -521,8 +664,15 @@ static int __init digest_lists_fs_init(void)
 	if (IS_ERR(digest_label_dentry))
 		goto out;
 
+	digest_query_dentry = securityfs_create_file("digest_query", 0600,
+						     digest_lists_dir, NULL,
+						     &digest_query_ops);
+	if (IS_ERR(digest_query_dentry))
+		goto out;
+
 	return 0;
 out:
+	securityfs_remove(digest_query_dentry);
 	securityfs_remove(digest_label_dentry);
 	securityfs_remove(digest_list_del_dentry);
 	securityfs_remove(digest_list_add_dentry);
-- 
2.25.1


  parent reply	other threads:[~2021-06-25 16:59 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-25 16:56 [RFC][PATCH 00/12] Huawei Digest Lists Roberto Sassu
2021-06-25 16:56 ` [RFC][PATCH 01/12] ima: Add digest, algo, measured parameters to ima_measure_critical_data() Roberto Sassu
2021-06-25 18:26   ` Mimi Zohar
2021-06-25 16:56 ` [RFC][PATCH 02/12] digest_lists: Overview Roberto Sassu
2021-06-25 16:56 ` [RFC][PATCH 03/12] digest_lists: Basic definitions Roberto Sassu
2021-06-27 10:53   ` Greg KH
2021-06-27 15:23     ` Matthew Wilcox
2021-06-27 15:35       ` Greg KH
2021-06-28  8:30     ` Roberto Sassu
2021-06-28  8:46       ` Greg KH
2021-06-28  9:27         ` Roberto Sassu
2021-06-28  9:32           ` Greg KH
2021-06-28  9:51             ` Roberto Sassu
2021-06-25 16:56 ` [RFC][PATCH 04/12] digest_lists: Objects Roberto Sassu
2021-06-27 10:56   ` Greg KH
2021-06-28  8:14     ` Roberto Sassu
2021-06-28  8:47       ` Greg KH
2021-06-25 16:56 ` [RFC][PATCH 05/12] digest_lists: Methods Roberto Sassu
2021-06-25 16:56 ` [RFC][PATCH 06/12] digest_lists: Parser Roberto Sassu
2021-06-25 16:56 ` [RFC][PATCH 07/12] digest_lists: Interfaces - digest_list_add, digest_list_del Roberto Sassu
2021-06-25 16:56 ` [RFC][PATCH 08/12] digest_lists: Interfaces - digest_lists_loaded Roberto Sassu
2021-06-25 16:56 ` [RFC][PATCH 09/12] digest_lists: Interfaces - digest_label Roberto Sassu
2021-06-25 16:56 ` Roberto Sassu [this message]
2021-06-25 16:56 ` [RFC][PATCH 11/12] digest_lists: Interfaces - digests_count Roberto Sassu
2021-06-25 22:07   ` kernel test robot
2021-06-25 16:56 ` [RFC][PATCH 12/12] digest_lists: Tests Roberto Sassu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210625165614.2284243-11-roberto.sassu@huawei.com \
    --to=roberto.sassu@huawei.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=zohar@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.