From patchwork Thu Nov 30 10:56:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 10084597 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 DE85F6035E for ; Thu, 30 Nov 2017 11:01:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BCCB429F39 for ; Thu, 30 Nov 2017 11:01:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AF4E829F3E; Thu, 30 Nov 2017 11:01:06 +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 2424029F37 for ; Thu, 30 Nov 2017 11:01:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751862AbdK3LBF (ORCPT ); Thu, 30 Nov 2017 06:01:05 -0500 Received: from lhrrgout.huawei.com ([194.213.3.17]:61899 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751859AbdK3LBF (ORCPT ); Thu, 30 Nov 2017 06:01:05 -0500 Received: from LHREML713-CAH.china.huawei.com (unknown [172.18.7.107]) by Forcepoint Email with ESMTP id CF09B69652E5E; Thu, 30 Nov 2017 11:01:01 +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 11:00:58 +0000 From: Roberto Sassu To: CC: , , Roberto Sassu Subject: [RFC][PATCH v2 7/9] ima: enforce the Biba low watermark for objects policy on appraised files Date: Thu, 30 Nov 2017 11:56:08 +0100 Message-ID: <20171130105610.15761-8-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 With this patch, IMA enforces a less restrictive integrity policy on appraised files. Instead of preventing processes outside the TCB from writing appraised files, IMA removes security.ima and then allows the operation. TCB processes won't be able to access demoted files anymore. Removing security.ima allows attacks to TCB to be detected by remote verifiers even if appraisal is not in enforcing mode. If an integrity model is selected, only files with a valid appraisal status will be excluded from measurement. Signed-off-by: Roberto Sassu --- Documentation/admin-guide/kernel-parameters.txt | 2 +- security/integrity/ima/ima.h | 3 ++- security/integrity/ima/ima_appraise.c | 29 ++++++++++++++++++++++--- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 6d184a94ba20..491fc3b312e7 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1534,7 +1534,7 @@ ima_integrity_model= [IMA] Select an integrity model. - Models: { "biba-strict" } + Models: { "biba-strict", "low-watermark-obj" } ima.ahash_minsize= [IMA] Minimum file size for asynchronous hash usage Format: diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index b9fdf0264c9d..ad615051e51b 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -36,7 +36,8 @@ enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN, IMA_SHOW_BINARY_OLD_STRING_FMT, IMA_SHOW_ASCII }; enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; -enum integrity_models { BIBA_STRICT = 1, INTEGRITY_POLICY__LAST }; +enum integrity_models { BIBA_STRICT = 1, BIBA_LOW_WATERMARK_OBJ, + INTEGRITY_POLICY__LAST }; /* digest size for IMA, fits SHA1 or MD5 */ #define IMA_DIGEST_SIZE SHA1_DIGEST_SIZE diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 27bbf48596cb..302d7e3ade65 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -22,6 +22,7 @@ int ima_integrity_model; static char *ima_integrity_models_str[INTEGRITY_POLICY__LAST] = { [BIBA_STRICT] = "biba-strict", + [BIBA_LOW_WATERMARK_OBJ] = "low-watermark-obj", }; static int __init default_appraise_setup(char *str) @@ -250,6 +251,7 @@ bool ima_inode_is_appraised(struct dentry *dentry, struct inode *inode) * * Integrity models: * - biba-strict: write down, read up + * - low-watermark-obj: read up * * Return: true if constraints are violated, false otherwise */ @@ -262,6 +264,8 @@ bool ima_appraise_integrity_check(struct file *file, fmode_t mode = file->f_mode; char *cause = "write_down_violation"; int expected_writecount = (mode & FMODE_WRITE) ? 1 : 0; + int expected_readcount = 0; + int violation = true; /* check write down violations */ if (!must_appraise && (mode & FMODE_WRITE)) { @@ -269,9 +273,9 @@ bool ima_appraise_integrity_check(struct file *file, if (!iint) iint = integrity_iint_find(inode); if (iint->flags & IMA_APPRAISED) - goto out_violation; + goto out_write_down_violation; } else if (ima_inode_is_appraised(file_dentry(file), inode)) { - goto out_violation; + goto out_write_down_violation; } /* concurrent write to non-TCB object by non-TCB subjects */ } else if (must_appraise && !(iint->flags & IMA_APPRAISED) && @@ -290,12 +294,31 @@ bool ima_appraise_integrity_check(struct file *file, } return false; +out_write_down_violation: + /* demote TCB object, if no concurrent access by TCB subjects */ + if (ima_integrity_model == BIBA_LOW_WATERMARK_OBJ) { + cause = "demote_failed_open_readers"; + if (mode & (FMODE_READ | FMODE_WRITE) == FMODE_READ) + expected_readcount = 1; + if (atomic_read(&inode->i_readcount) == expected_readcount) { + if (iint) + iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED | + IMA_APPRAISE_SUBMASK | + IMA_APPRAISED_SUBMASK | + IMA_ACTION_RULE_FLAGS); + + __vfs_removexattr(file->f_path.dentry, XATTR_NAME_IMA); + + violation = false; + cause = "demote_successful"; + } + } out_violation: *pathname = ima_d_path(&file->f_path, pathbuf, namebuf); integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, *pathname, ima_integrity_models_str[ima_integrity_model], cause, 0, 0); - return true; + return violation; } /*