Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp710049pxj; Wed, 16 Jun 2021 11:44:04 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxRf8iOe+rXUQ3patxNy7yd6q1KbMzn9ssEuU9fq3fjyqwlptmkoyEqfq6A2VWvpIIgeEkV X-Received: by 2002:a17:907:1b29:: with SMTP id mp41mr929981ejc.459.1623869044762; Wed, 16 Jun 2021 11:44:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623869044; cv=none; d=google.com; s=arc-20160816; b=FBEBAToYrbeOFtCGhfzW/fJunHyxMW5ODzt4tRVpZESBm7gXUpaD7241jkeXMiozlB TUnL9UqrxTmXqkE+xTpX1V0e7/fOhin5/yBx59dCcNEbaGE2sP6vsPdNoOif5zR4Ltmh E4haY3EfrpcgEtp2v0RBNWQ15CtAztS5nQANPDSoPy+xHoMUqcqj6hA/cTRwpEdmXdY9 uFzni/I4ZKniZPQBHsI4hpt1hR6MKie6DjgE7L+tQk5kaHsZ2PQ/PnoyZWQ1uIg7iqCg ZGlkc/NBj1UK5F6iMJf9DJu2Jx/a6pgVzRuQKwwdipu/QnFu2zI7pjmzhiu3kMfYEThm ezaw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=N6lUZfo23wZEjJ4m9hr2ljvm9emIiZ5+BsNdlMQiwvA=; b=zX29L6RZuVRjs1LfAWxzSZdcNQZZHhuev4ktfUndLQT6iSuzxds9nNPev8NEcpq4ra PPsp+/iPc5bmcAyvMA4zfJnyyKKTpCuWi+ydi9hfgCXNMLxDD0awM3qk1kbH3yUgTnXV CckvDgzYVkKZu5bUQMa7gbXaYPnbr2ogy2fmjtS28EtMWblULF07GMzsmbXypVvIbRlA RjwQlsBp6cjoiE94Y7OFqYRlJZ8dPl7SGMAUC1/glmlUvsCELkveMXYx7wTKYEdOpQea kd+zofglyT6DCZotugd+x//bw3BkhLcli7rVq69AMU5ZX77s+/HG5zBB+cQ6no+3oR+B XOwQ== 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=huawei.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id u5si3178752ejn.571.2021.06.16.11.43.41; Wed, 16 Jun 2021 11:44:04 -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=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233155AbhFPNYw (ORCPT + 99 others); Wed, 16 Jun 2021 09:24:52 -0400 Received: from frasgout.his.huawei.com ([185.176.79.56]:3250 "EHLO frasgout.his.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232611AbhFPNYu (ORCPT ); Wed, 16 Jun 2021 09:24:50 -0400 Received: from fraeml714-chm.china.huawei.com (unknown [172.18.147.201]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4G4lwq6C9Kz6K6NG; Wed, 16 Jun 2021 21:12:59 +0800 (CST) Received: from roberto-ThinkStation-P620.huawei.com (10.204.62.217) by fraeml714-chm.china.huawei.com (10.206.15.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2176.2; Wed, 16 Jun 2021 15:22:40 +0200 From: Roberto Sassu To: , , , , , CC: , , , , , Roberto Sassu Subject: [PATCH] fs: Return raw xattr for security.* if there is size disagreement with LSMs Date: Wed, 16 Jun 2021 15:22:27 +0200 Message-ID: <20210616132227.999256-1-roberto.sassu@huawei.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [10.204.62.217] X-ClientProxiedBy: lhreml754-chm.china.huawei.com (10.201.108.204) To fraeml714-chm.china.huawei.com (10.206.15.33) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org vfs_getxattr() differs from vfs_setxattr() in the way it obtains the xattr value. The former gives precedence to the LSMs, and if the LSMs don't provide a value, obtains it from the filesystem handler. The latter does the opposite, first invokes the filesystem handler, and if the filesystem does not support xattrs, passes the xattr value to the LSMs. The problem is that not necessarily the user gets the same xattr value that he set. For example, if he sets security.selinux with a value not terminated with '\0', he gets a value terminated with '\0' because SELinux adds it during the translation from xattr to internal representation (vfs_setxattr()) and from internal representation to xattr (vfs_getxattr()). Normally, this does not have an impact unless the integrity of xattrs is verified with EVM. The kernel and the user see different values due to the different functions used to obtain them: kernel (EVM): uses vfs_getxattr_alloc() which obtains the xattr value from the filesystem handler (raw value); user (ima-evm-utils): uses vfs_getxattr() which obtains the xattr value from the LSMs (normalized value). Given that the difference between the raw value and the normalized value should be just the additional '\0' not the rest of the content, this patch modifies vfs_getxattr() to compare the size of the xattr value obtained from the LSMs to the size of the raw xattr value. If there is a mismatch and the filesystem handler does not return an error, vfs_getxattr() returns the raw value. This patch should have a minimal impact on existing systems, because if the SELinux label is written with the appropriate tools such as setfiles or restorecon, there will not be a mismatch (because the raw value also has '\0'). In the case where the SELinux label is written directly with setfattr and without '\0', this patch helps to align EVM and ima-evm-utils in terms of result provided (due to the fact that they both verify the integrity of xattrs from raw values). Signed-off-by: Roberto Sassu Tested-by: Mimi Zohar --- fs/xattr.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/fs/xattr.c b/fs/xattr.c index 5c8c5175b385..412ec875aa07 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -420,12 +420,27 @@ vfs_getxattr(struct user_namespace *mnt_userns, struct dentry *dentry, const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; int ret = xattr_getsecurity(mnt_userns, inode, suffix, value, size); + int ret_raw; + /* * Only overwrite the return value if a security module * is actually active. */ if (ret == -EOPNOTSUPP) goto nolsm; + + if (ret < 0) + return ret; + + /* + * Read raw xattr if the size from the filesystem handler + * differs from that returned by xattr_getsecurity() and is + * equal or greater than zero. + */ + ret_raw = __vfs_getxattr(dentry, inode, name, NULL, 0); + if (ret_raw >= 0 && ret_raw != ret) + goto nolsm; + return ret; } nolsm: -- 2.25.1