Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp332141ybz; Wed, 29 Apr 2020 00:44:11 -0700 (PDT) X-Google-Smtp-Source: APiQypKNknsSDiCs8kom1a9NY8bpjfDSznLu5x+PI/3ynRBjY48/jyNWAtNR+CbGnplb4B6vbC27 X-Received: by 2002:a17:906:e01:: with SMTP id l1mr1384325eji.76.1588146250947; Wed, 29 Apr 2020 00:44:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1588146250; cv=none; d=google.com; s=arc-20160816; b=oFaavvR5jggakQ4/4VuOQ1+l1Du77Awk6UY+Tsup9jenoH0ce4pDvedKdymBeP9Mq9 i+n607oaRJn35tnkJCIAoPY25369ZkwMa/sXuQt6MxQzrXa+SPlYzY+iRNg/U+FmRQvE AB8NLCAEP4Nf82E9n2E53khIF2p2PMF4oH1vyPczb7Z4hA8lWeLFoKvJZaf9Et45p3rG ms9gFDyn6IAovTfTAAUxIs+58lkPkvRZMv3w5ioUolQSkC2KXYHynaJUzBaU9FOAk9ks 2sj14IsGcCWWDzTWQ1SGOO8EqJ+zbH5TF0kx0/Vf5i0vLe2y4TwkIYrWnfCIgCh3nbHG uuWw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from; bh=s52D0SLOyrIJ9N/w14wAiQjhGRw9z+hiBqX1JqWf6wU=; b=Jof3QT7U3t/Hok8J0yWKEmNliraDhcAgPgDJfUZmF7xv+ILCvRntJeyReHLfTcgLX6 rcCXCgE8iNMzvolVVnDNSKCMEE6On4s1LJ3F0+STwIdBCtTexdJL7e5t0xYWT4J9dWwA oMnDmfqAGHMDUFRNMvuJ5u57HbxJGwdXQL+eudyF/q9CMB6Bh7ka3ju+RtGYV79NvvEO P5nnt0XjaTpc5jC70Z/um6VPG8xxqoFUzo1tXFFaD9baARDJc0++rEIHrsLws9WSUbT8 T/M6Rq9wYocaxbjP9u/kSFG7mMl0mg7FhLNFHA99enl7eVgy7HOIyr541AcdjxsGKc+W ek/A== 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id v2si3406635edd.536.2020.04.29.00.43.47; Wed, 29 Apr 2020 00:44:10 -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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726739AbgD2HmQ (ORCPT + 99 others); Wed, 29 Apr 2020 03:42:16 -0400 Received: from lhrrgout.huawei.com ([185.176.76.210]:2127 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726554AbgD2HmN (ORCPT ); Wed, 29 Apr 2020 03:42:13 -0400 Received: from lhreml707-chm.china.huawei.com (unknown [172.18.7.107]) by Forcepoint Email with ESMTP id 4A1DB5F8236ABC6C97AB; Wed, 29 Apr 2020 08:42:11 +0100 (IST) Received: from fraeml714-chm.china.huawei.com (10.206.15.33) by lhreml707-chm.china.huawei.com (10.201.108.56) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1913.5; Wed, 29 Apr 2020 08:42:10 +0100 Received: from roberto-HP-EliteDesk-800-G2-DM-65W.huawei.com (10.204.65.160) by fraeml714-chm.china.huawei.com (10.206.15.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.1913.5; Wed, 29 Apr 2020 09:42:10 +0200 From: Roberto Sassu To: , , , CC: , , , , , Roberto Sassu Subject: [RFC][PATCH 3/3] evm: Return -EAGAIN to ignore verification failures Date: Wed, 29 Apr 2020 09:39:35 +0200 Message-ID: <20200429073935.11913-3-roberto.sassu@huawei.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200429073935.11913-1-roberto.sassu@huawei.com> References: <20200429073935.11913-1-roberto.sassu@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.204.65.160] X-ClientProxiedBy: lhreml701-chm.china.huawei.com (10.201.108.50) To fraeml714-chm.china.huawei.com (10.206.15.33) X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org By default, EVM maintains the same behavior as before hooks were moved outside the LSM infrastructure. When EVM returns -EPERM, callers stop their execution and return the error to user space. This patch introduces a new mode, called ignore, that changes the return value of the pre hooks from -EPERM to -EAGAIN. It also modifies the callers of pre and post hooks to continue the execution if -EAGAIN is returned. The error is then handled by the post hooks. The only error that is not ignored is when user space is trying to modify a portable signature. Once that signature has been validated with the current values of metadata, there is no valid reason to change them. From user space perspective, operations on corrupted metadata are successfully performed but post hooks didn't update the HMAC. At the next IMA verification, when evm_verifyxattr() is called, corruption will be detected and access will be denied. Signed-off-by: Roberto Sassu --- fs/attr.c | 2 +- fs/xattr.c | 4 ++-- security/integrity/evm/evm_main.c | 23 +++++++++++++++++------ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 6ce60e1eba34..6370e2f3704d 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -329,7 +329,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de if (error) return error; evm_error = evm_inode_setattr(dentry, attr); - if (evm_error) + if (evm_error && evm_error != -EAGAIN) return evm_error; error = try_break_deleg(inode, delegated_inode); if (error) diff --git a/fs/xattr.c b/fs/xattr.c index b1fd2aa481a8..73f0f3cd6c45 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -229,7 +229,7 @@ vfs_setxattr(struct dentry *dentry, const char *name, const void *value, goto out; evm_error = evm_inode_setxattr(dentry, name, value, size); - if (evm_error) { + if (evm_error && evm_error != -EAGAIN) { error = evm_error; goto out; } @@ -408,7 +408,7 @@ vfs_removexattr(struct dentry *dentry, const char *name) goto out; evm_error = evm_inode_removexattr(dentry, name); - if (evm_error) { + if (evm_error && evm_error != -EAGAIN) { error = evm_error; goto out; } diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index ca9eaef7058b..ef09caa3bbcf 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -54,11 +54,13 @@ static struct xattr_list evm_config_default_xattrnames[] = { LIST_HEAD(evm_config_xattrnames); -static int evm_fixmode; +static int evm_fixmode, evm_ignoremode __ro_after_init; static int __init evm_set_fixmode(char *str) { if (strncmp(str, "fix", 3) == 0) evm_fixmode = 1; + if (strncmp(str, "ignore", 6) == 0) + evm_ignoremode = 1; return 0; } __setup("evm=", evm_set_fixmode); @@ -311,6 +313,7 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name, const void *xattr_value, size_t xattr_value_len) { enum integrity_status evm_status; + int rc = -EPERM; if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) { if (!capable(CAP_SYS_ADMIN)) @@ -345,12 +348,17 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name, -EPERM, 0); } out: - if (evm_status != INTEGRITY_PASS) + if (evm_status != INTEGRITY_PASS) { + if (evm_ignoremode && evm_status != INTEGRITY_PASS_IMMUTABLE) + rc = -EAGAIN; + integrity_audit_msg(AUDIT_INTEGRITY_METADATA, d_backing_inode(dentry), dentry->d_name.name, "appraise_metadata", integrity_status_msg[evm_status], - -EPERM, 0); - return evm_status == INTEGRITY_PASS ? 0 : -EPERM; + rc, 0); + } + + return evm_status == INTEGRITY_PASS ? 0 : rc; } /** @@ -482,6 +490,7 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr) { unsigned int ia_valid = attr->ia_valid; enum integrity_status evm_status; + int rc = -EPERM; /* Policy permits modification of the protected attrs even though * there's no HMAC key loaded @@ -495,10 +504,12 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr) if ((evm_status == INTEGRITY_PASS) || (evm_status == INTEGRITY_NOXATTRS)) return 0; + if (evm_ignoremode && evm_status != INTEGRITY_PASS_IMMUTABLE) + rc = -EAGAIN; integrity_audit_msg(AUDIT_INTEGRITY_METADATA, d_backing_inode(dentry), dentry->d_name.name, "appraise_metadata", - integrity_status_msg[evm_status], -EPERM, 0); - return -EPERM; + integrity_status_msg[evm_status], rc, 0); + return rc; } /** -- 2.17.1