Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753123AbdGYPuO (ORCPT ); Tue, 25 Jul 2017 11:50:14 -0400 Received: from lhrrgout.huawei.com ([194.213.3.17]:32205 "EHLO lhrrgout.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752950AbdGYPuM (ORCPT ); Tue, 25 Jul 2017 11:50:12 -0400 From: Roberto Sassu To: CC: , , , , Roberto Sassu Subject: [PATCH 05/12] ima: add functions to manage digest lists Date: Tue, 25 Jul 2017 17:44:16 +0200 Message-ID: <20170725154423.24845-6-roberto.sassu@huawei.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170725154423.24845-1-roberto.sassu@huawei.com> References: <20170725154423.24845-1-roberto.sassu@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.204.65.245] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020204.597768B1.0253,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 5c78f7a9c4bd275441b0b5fc0cacdfe7 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3541 Lines: 103 This patch first introduces a new structure called ima_digest, which will contain a digest parsed from the digest list. It has been preferred to ima_queue_entry, as the existing structure includes an additional member (a list head), which is not necessary for digest lookup. Then, this patch introduces functions to lookup and add a digest to a hash table, which will be used by the parsers. Signed-off-by: Roberto Sassu --- security/integrity/ima/ima.h | 8 ++++++++ security/integrity/ima/ima_queue.c | 39 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index d52b487..a0c6808 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -107,6 +107,11 @@ struct ima_queue_entry { }; extern struct list_head ima_measurements; /* list of all measurements */ +struct ima_digest { + struct hlist_node hnext; + u8 digest[0]; +}; + /* Some details preceding the binary serialized measurement list */ struct ima_kexec_hdr { u16 version; @@ -150,6 +155,8 @@ void ima_print_digest(struct seq_file *m, u8 *digest, u32 size); struct ima_template_desc *ima_template_desc_current(void); int ima_restore_measurement_entry(struct ima_template_entry *entry); int ima_restore_measurement_list(loff_t bufsize, void *buf); +struct ima_digest *ima_lookup_loaded_digest(u8 *digest); +int ima_add_digest_data_entry(u8 *digest); int ima_measurements_show(struct seq_file *m, void *v); unsigned long ima_get_binary_runtime_size(void); int ima_init_template(void); @@ -166,6 +173,7 @@ struct ima_h_table { struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE]; }; extern struct ima_h_table ima_htable; +extern struct ima_h_table ima_digests_htable; static inline unsigned long ima_hash_key(u8 *digest) { diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index a02a86d..d1a3d3f 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -42,6 +42,11 @@ struct ima_h_table ima_htable = { .queue[0 ... IMA_MEASURE_HTABLE_SIZE - 1] = HLIST_HEAD_INIT }; +struct ima_h_table ima_digests_htable = { + .len = ATOMIC_LONG_INIT(0), + .queue[0 ... IMA_MEASURE_HTABLE_SIZE - 1] = HLIST_HEAD_INIT +}; + /* mutex protects atomicity of extending measurement list * and extending the TPM PCR aggregate. Since tpm_extend can take * long (and the tpm driver uses a mutex), we can't use the spinlock. @@ -212,3 +217,37 @@ int ima_restore_measurement_entry(struct ima_template_entry *entry) mutex_unlock(&ima_extend_list_mutex); return result; } + +struct ima_digest *ima_lookup_loaded_digest(u8 *digest) +{ + struct ima_digest *d = NULL; + int digest_len = hash_digest_size[ima_hash_algo]; + unsigned int key = ima_hash_key(digest); + + rcu_read_lock(); + hlist_for_each_entry_rcu(d, &ima_digests_htable.queue[key], hnext) { + if (memcmp(d->digest, digest, digest_len) == 0) + break; + } + rcu_read_unlock(); + return d; +} + +int ima_add_digest_data_entry(u8 *digest) +{ + struct ima_digest *d = ima_lookup_loaded_digest(digest); + int digest_len = hash_digest_size[ima_hash_algo]; + unsigned int key = ima_hash_key(digest); + + if (d) + return -EEXIST; + + d = kmalloc(sizeof(*d) + digest_len, GFP_KERNEL); + if (d == NULL) + return -ENOMEM; + + memcpy(d->digest, digest, digest_len); + hlist_add_head_rcu(&d->hnext, &ima_digests_htable.queue[key]); + atomic_long_inc(&ima_digests_htable.len); + return 0; +} -- 2.9.3