Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp624497ybz; Wed, 15 Apr 2020 15:22:21 -0700 (PDT) X-Google-Smtp-Source: APiQypKMt4O0Z7vR35Fbap/+fzVn/9w5+WLhikvtaL1fXq0wzvKL/nqiOM4lJIcINss7hjusfC4J X-Received: by 2002:a17:906:138c:: with SMTP id f12mr7223860ejc.35.1586989341093; Wed, 15 Apr 2020 15:22:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1586989341; cv=none; d=google.com; s=arc-20160816; b=OBCsL7BOOu4x3iKdN13TIgR51ccwag+gFDwTVqDLqJgJYskN8xttl6Ut3fbSPI1bqy 8YEN+MBIqrpgI1T4/wue9W6Ki+0tN3jsU6YJ3qqIvVE4zQJAhOvXPT22QWcxX+gT0af9 hyu1UW7bVIBhZSOfnLofccwjRfXjCI90Dp7t0vv4fCTiKC6VkNy33OOj3vlRIYLhZGWt Uwc9UjZHwf7p0lxzm0M72h4rjSeTo9OPh0v6L8Vdt3TKHuEgGSpGV3HWJmKSFkJpyQCz q9FE4q91I0XMdX29fhzkj9AxwGisGQGVRWYzsZXV7SCzOFfS0B5B8z66cLDdPg42u2JM 9tzw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from; bh=pf8VSTflgOmNWKM9qFQEqo7DekhPR1AuIxVrCmSBoLU=; b=ccMmtinc14pR1/wx6iaQ1xhshfhVxsRQ011rC97Gp++IB99BZDwn6tqUmAN2aerLy+ XdvtB6MBbtIlHu0M3rLi1L9cCkKWCFitnVi2CcV5Je5B7ETgqGNcXr46MIlboO4g+TzO PJeEBEdmc6JnErU5dlWmoNLBDthQqg2aXTyg5/+AKoI3PsbSo5wnbfw7geIlpbFfDOat 06p4hq55gJHzi+83bIX1ZMFBkE2wBhLn/8ojLVZK9nGapSizYIfyC/pq6WS76YdhL9jI UuuBnrXuxZm617V8P818nGH87xAgFbUBt/gyCDNs31MrUHSI2un+QT3B87kfozlQ5X6W SrYg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id r18si10663067ejj.211.2020.04.15.15.21.57; Wed, 15 Apr 2020 15:22:21 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2635346AbgDOHyM (ORCPT + 99 others); Wed, 15 Apr 2020 03:54:12 -0400 Received: from out30-54.freemail.mail.aliyun.com ([115.124.30.54]:35812 "EHLO out30-54.freemail.mail.aliyun.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2635345AbgDOHwh (ORCPT ); Wed, 15 Apr 2020 03:52:37 -0400 X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R721e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e01419;MF=tianjia.zhang@linux.alibaba.com;NM=1;PH=DS;RN=10;SR=0;TI=SMTPD_---0TvbELz._1586937149; Received: from localhost(mailfrom:tianjia.zhang@linux.alibaba.com fp:SMTPD_---0TvbELz._1586937149) by smtp.aliyun-inc.com(127.0.0.1); Wed, 15 Apr 2020 15:52:30 +0800 From: Tianjia Zhang To: zohar@linux.ibm.com, dmitry.kasatkin@gmail.com, jmorris@namei.org, serge@hallyn.com, zhangliguang@linux.alibaba.com, zhang.jia@linux.alibaba.com Cc: linux-integrity@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, tianjia.zhang@linux.alibaba.com Subject: [PATCH v2] ima: optimize ima_pcr_extend function by asynchronous Date: Wed, 15 Apr 2020 15:52:29 +0800 Message-Id: <20200415075229.71595-1-tianjia.zhang@linux.alibaba.com> X-Mailer: git-send-email 2.17.1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Because ima_pcr_extend() to operate the TPM chip, this process is very time-consuming, for IMA, this is a blocking action, especially when the TPM is in self test state, this process will block for up to second level. Because the return result of ima_pcr_extend() is of no concern to IMA, it only affects the audit of IMA, so this patch use async_schedule() and PCR extend event serial queue to asynchronously perform the ima_pcr_extend() operation and do an audit operation at the end. In a vtpm scenario, I added the measure policy of BPRM and MMAP to compare the efficiency before and after applying the patch. The results show that the overall startup efficiency of conventional processes can be increased by 5% to 10%. I believe this efficiency increase It will be more obvious on real hardware tpm. Signed-off-by: Tianjia Zhang --- v2 chang: Use a queue to queue tpm extend operations to avoid out of order security/integrity/ima/ima_queue.c | 102 +++++++++++++++++++++++------ 1 file changed, 81 insertions(+), 21 deletions(-) diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index edbc2d6962be..ec146270d94b 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -17,6 +17,7 @@ #include #include +#include #include "ima.h" #define AUDIT_CAUSE_LEN_MAX 32 @@ -44,6 +45,21 @@ struct ima_h_table ima_htable = { */ static DEFINE_MUTEX(ima_extend_list_mutex); +/* list for pcr extned asynchronous */ +static LIST_HEAD(ima_pcr_extend_list); + +struct ima_pcr_extend_async_ctx { + struct list_head list; + struct ima_template_entry *entry; + int violation; + const char *op; + struct inode *inode; + const unsigned char *filename; + const char *audit_cause; + int audit_info; + int result; +}; + /* lookup up the digest value in the hash table, and return the entry */ static struct ima_queue_entry *ima_lookup_digest_entry(u8 *digest_value, int pcr) @@ -150,6 +166,48 @@ static int ima_pcr_extend(const u8 *hash, int pcr) return result; } +static void ima_pcr_extend_async(void *data, async_cookie_t cookie) +{ + struct ima_pcr_extend_async_ctx *ctx; + u8 digest[TPM_DIGEST_SIZE]; + char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX]; + int empty; + int result; + +retry: + mutex_lock(&ima_extend_list_mutex); + empty = list_empty(&ima_pcr_extend_list); + if (!empty) { + ctx = list_first_entry(&ima_pcr_extend_list, + struct ima_pcr_extend_async_ctx, list); + list_del(&ctx->list); + } + mutex_unlock(&ima_extend_list_mutex); + + /* no more pending pcr_extend, return */ + if (empty) + return; + + if (ctx->violation) /* invalidate pcr */ + memset(digest, 0xff, sizeof(digest)); + else + memcpy(digest, ctx->entry->digest, sizeof(digest)); + + result = ima_pcr_extend(digest, ctx->entry->pcr); + if (result != 0) { + snprintf(tpm_audit_cause, AUDIT_CAUSE_LEN_MAX, "TPM_error(%d)", + result); + ctx->audit_cause = tpm_audit_cause; + ctx->audit_info = 0; + } + integrity_audit_msg(AUDIT_INTEGRITY_PCR, ctx->inode, ctx->filename, + ctx->op, ctx->audit_cause, + ctx->result, ctx->audit_info); + + kfree(ctx); + goto retry; +} + /* * Add template entry to the measurement list and hash table, and * extend the pcr. @@ -162,20 +220,16 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation, const char *op, struct inode *inode, const unsigned char *filename) { - u8 digest[TPM_DIGEST_SIZE]; const char *audit_cause = "hash_added"; - char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX]; int audit_info = 1; - int result = 0, tpmresult = 0; + int result = 0; + struct ima_pcr_extend_async_ctx *ctx; mutex_lock(&ima_extend_list_mutex); - if (!violation) { - memcpy(digest, entry->digest, sizeof(digest)); - if (ima_lookup_digest_entry(digest, entry->pcr)) { - audit_cause = "hash_exists"; - result = -EEXIST; - goto out; - } + if (!violation && ima_lookup_digest_entry(entry->digest, entry->pcr)) { + audit_cause = "hash_exists"; + result = -EEXIST; + goto out; } result = ima_add_digest_entry(entry, 1); @@ -185,20 +239,26 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation, goto out; } - if (violation) /* invalidate pcr */ - memset(digest, 0xff, sizeof(digest)); - - tpmresult = ima_pcr_extend(digest, entry->pcr); - if (tpmresult != 0) { - snprintf(tpm_audit_cause, AUDIT_CAUSE_LEN_MAX, "TPM_error(%d)", - tpmresult); - audit_cause = tpm_audit_cause; - audit_info = 0; + ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) { + audit_cause = "ENOMEM"; + result = -ENOMEM; + goto out; } + + ctx->entry = entry; + ctx->violation = violation; + ctx->op = op; + ctx->inode = inode; + ctx->filename = filename; + ctx->audit_cause = audit_cause; + ctx->audit_info = audit_info; + ctx->result = result; + list_add_tail(&ctx->list, &ima_pcr_extend_list); + async_schedule(ima_pcr_extend_async, NULL); + out: mutex_unlock(&ima_extend_list_mutex); - integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, - op, audit_cause, result, audit_info); return result; } -- 2.17.1