From patchwork Thu Nov 30 10:56:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 10084581 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id EFA8C6035E for ; Thu, 30 Nov 2017 10:58:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CDA1129F37 for ; Thu, 30 Nov 2017 10:58:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C2B2D29F3B; Thu, 30 Nov 2017 10:58:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6096F29F37 for ; Thu, 30 Nov 2017 10:58:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751443AbdK3K67 (ORCPT ); Thu, 30 Nov 2017 05:58:59 -0500 Received: from lhrrgout.huawei.com ([194.213.3.17]:61895 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751177AbdK3K66 (ORCPT ); Thu, 30 Nov 2017 05:58:58 -0500 Received: from LHREML713-CAH.china.huawei.com (unknown [172.18.7.107]) by Forcepoint Email with ESMTP id 188514DAB45EF; Thu, 30 Nov 2017 10:58:55 +0000 (GMT) Received: from localhost.localdomain (10.204.65.254) by smtpsuk.huawei.com (10.201.108.36) with Microsoft SMTP Server (TLS) id 14.3.361.1; Thu, 30 Nov 2017 10:58:48 +0000 From: Roberto Sassu To: CC: , , Roberto Sassu Subject: [RFC][PATCH v2 3/9] ima: preserve iint flags if security.ima update is successful Date: Thu, 30 Nov 2017 11:56:04 +0100 Message-ID: <20171130105610.15761-4-roberto.sassu@huawei.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171130105610.15761-1-roberto.sassu@huawei.com> References: <20171130105610.15761-1-roberto.sassu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.204.65.254] X-CFilter-Loop: Reflected Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP During the last file close, IMA clears the flags in the IMA_DONE_MASK, to ensure that files are measured and audited after they have been modified. However, if security.ima is correctly updated, it wouldn't be necessary to clear also the appraisal flags, because in this case the appraisal status is valid. This patch modifies ima_update_xattr() to return the result of the security.ima update. If the operation is done successfully, ima_check_last_writer() preserves the IMA_APPRAISED and IMA_APPRAISED_SUBMASK iint flags. Signed-off-by: Roberto Sassu --- security/integrity/ima/ima.h | 6 +++--- security/integrity/ima/ima_appraise.c | 10 +++++----- security/integrity/ima/ima_main.c | 11 +++++++++-- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 0703a96072b5..2bdf10417125 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -241,7 +241,7 @@ int ima_appraise_measurement(enum ima_hooks func, struct evm_ima_xattr_data *xattr_value, int xattr_len, int opened); int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); -void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); +int ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, enum ima_hooks func); enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, @@ -266,8 +266,8 @@ static inline int ima_must_appraise(struct inode *inode, int mask, return 0; } -static inline void ima_update_xattr(struct integrity_iint_cache *iint, - struct file *file) +static inline int ima_update_xattr(struct integrity_iint_cache *iint, + struct file *file) { } diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index a54ad18affb1..23e025e86aed 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -319,23 +319,23 @@ int ima_appraise_measurement(enum ima_hooks func, /* * ima_update_xattr - update 'security.ima' hash value */ -void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file) +int ima_update_xattr(struct integrity_iint_cache *iint, struct file *file) { struct dentry *dentry = file_dentry(file); int rc = 0; /* do not collect and update hash for digital signatures */ if (iint->flags & IMA_DIGSIG) - return; + return -EPERM; if (iint->ima_file_status != INTEGRITY_PASS) - return; + return -EPERM; rc = ima_collect_measurement(iint, file, NULL, 0, ima_hash_algo); if (rc < 0) - return; + return rc; - ima_fix_xattr(dentry, iint); + return ima_fix_xattr(dentry, iint); } /** diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 5a7321bc325c..fb144177a783 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -121,6 +121,8 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint, struct inode *inode, struct file *file) { fmode_t mode = file->f_mode; + u64 appraise_flags; + int rc; if (!(mode & FMODE_WRITE)) return; @@ -129,10 +131,15 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint, if (atomic_read(&inode->i_writecount) == 1) { if ((iint->version != inode->i_version) || (iint->flags & IMA_NEW_FILE)) { + appraise_flags = iint->flags & (IMA_APPRAISED | + IMA_APPRAISED_SUBMASK); iint->flags &= ~(IMA_DONE_MASK | IMA_NEW_FILE); iint->measured_pcrs = 0; - if (iint->flags & IMA_APPRAISE) - ima_update_xattr(iint, file); + if (iint->flags & IMA_APPRAISE) { + rc = ima_update_xattr(iint, file); + if (!rc) + iint->flags |= appraise_flags; + } } } inode_unlock(inode);