Message ID | 20221110094639.3086409-3-roberto.sassu@huaweicloud.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp47551wru; Thu, 10 Nov 2022 01:49:18 -0800 (PST) X-Google-Smtp-Source: AMsMyM7FLCWUKLfXXqskdCDqAb4mj2siaKNWYHD/9hTZlcV1jJ0pSnOW/jO1jUyDk4I3qAAn3oHp X-Received: by 2002:a05:6a00:1483:b0:56b:ab8e:f44a with SMTP id v3-20020a056a00148300b0056bab8ef44amr63981129pfu.85.1668073758608; Thu, 10 Nov 2022 01:49:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668073758; cv=none; d=google.com; s=arc-20160816; b=mgDyCzdolhNTvGUIzn6Cz305cfxLYelOXG3djBl96MP4inM5bO7gSvzJ/LplxpuUXd jBfevfxTCcDhdb0lobcgikvzwUUNVQkITCTKh1ot5FNK8QIIX2dpbe5vnw3Y0d8ef5Ga 21dfIEHhbab1qmjSBHvufSyLjK8Drt5lBi46sNpsVaTKxSHqKhZvQPdmoW9uY/tuE/5V L4VzSlI8XS1kloK+PUPMh4wM+AqSmyw9VidI65Lb7ZhkLd2Wm3vZhX4UgRTIpK/JU0ux rPtFEirbfQ8TPMg7d2SWW9AaMryz3BTTW1TWHfJ7aFciyj4BMcaK/+wXKewPCDaj7dqM lVuA== 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=pfCIXEumnlxzAc+8msyZEF83kFXl8LXgalsSaJtF3eE=; b=tZcdt8jMaimv01HruzzrLR6OqXMi04L12cjpRSaR0s2VkHDl5pPrR73zvNgHXZ0/o4 7d6ATC0qI6dJJxqzU67nIc2tET0XsIGRQsVhUqk01DbYMqEs9U7W+nQ1C5h8sT1tC4LJ BzO3LU7+Mepyya7bgMr8coq/06yuVfw86NWYAqlvywQakbjLmSrpPnoDhwHpFV3t0Wog bilhZyQH+Wls/mxT5dA6PFQ3s7+g2/wZ+y2iZDl9J6XvqI1fHO8LlI9aBQcB6Ai8/qP1 vgyi8Y4mriLr3iKMeMPGbxCLUV4DFXJAzlkXPQOYiIW194lxBlRZfKNubB/IJtI7YeDB cVmg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b3-20020a170902d50300b001783ba6f79dsi24384965plg.494.2022.11.10.01.49.04; Thu, 10 Nov 2022 01:49:18 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230055AbiKJJr4 (ORCPT <rfc822;winker.wchi@gmail.com> + 99 others); Thu, 10 Nov 2022 04:47:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35068 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230022AbiKJJrq (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 10 Nov 2022 04:47:46 -0500 Received: from frasgout13.his.huawei.com (frasgout13.his.huawei.com [14.137.139.46]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 38D926AEF3; Thu, 10 Nov 2022 01:47:41 -0800 (PST) Received: from mail02.huawei.com (unknown [172.18.147.228]) by frasgout13.his.huawei.com (SkyGuard) with ESMTP id 4N7Gzx6w8Dz9xFHR; Thu, 10 Nov 2022 17:41:01 +0800 (CST) Received: from huaweicloud.com (unknown [10.204.63.22]) by APP1 (Coremail) with SMTP id LxC2BwCHc3CNyGxjO3hSAA--.1123S4; Thu, 10 Nov 2022 10:47:18 +0100 (CET) From: Roberto Sassu <roberto.sassu@huaweicloud.com> To: zohar@linux.ibm.com, dmitry.kasatkin@gmail.com, paul@paul-moore.com, jmorris@namei.org, serge@hallyn.com, stephen.smalley.work@gmail.com, eparis@parisplace.org, casey@schaufler-ca.com Cc: linux-integrity@vger.kernel.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, reiserfs-devel@vger.kernel.org, linux-kernel@vger.kernel.org, keescook@chromium.org, nicolas.bouchinet@clip-os.org, Roberto Sassu <roberto.sassu@huawei.com> Subject: [PATCH v4 2/5] security: Rewrite security_old_inode_init_security() Date: Thu, 10 Nov 2022 10:46:36 +0100 Message-Id: <20221110094639.3086409-3-roberto.sassu@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221110094639.3086409-1-roberto.sassu@huaweicloud.com> References: <20221110094639.3086409-1-roberto.sassu@huaweicloud.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID: LxC2BwCHc3CNyGxjO3hSAA--.1123S4 X-Coremail-Antispam: 1UD129KBjvJXoWxXr47uw45CrW5tFyfWF1Utrb_yoWrWr47pF 43K3WUCr1rJF97WrWfta17u3WSkFWrGrsrAws3C3sFyF1DCr1xtryFyF15Cr15XrW8Jr1v qw4avr15Gwn8J3JanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUBYb4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUXw A2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxS w2x7M28EF7xvwVC0I7IYx2IY67AKxVWUJVWUCwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxV WxJVW8Jr1l84ACjcxK6I8E87Iv67AKxVW8JVWxJwA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_ Gr0_Gr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMc Ij6xIIjxv20xvE14v26r1j6r18McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_ Jr0_Gr1lF7xvr2IYc2Ij64vIr41lFIxGxcIEc7CjxVA2Y2ka0xkIwI1l42xK82IYc2Ij64 vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8G jcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r4a6rW5MIIYrxkI7VAKI48JMIIF0xvE2I x0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJwCI42IY6xAI w20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x 0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7IU1sa9DUUUUU== X-CM-SenderInfo: purev21wro2thvvxqx5xdzvxpfor3voofrz/1tbiAgAMBF1jj4FHEgAAsv X-CFilter-Loop: Reflected X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749102109295923914?= X-GMAIL-MSGID: =?utf-8?q?1749102109295923914?= |
Series |
evm: Prepare for moving to the LSM infrastructure
|
|
Commit Message
Roberto Sassu
Nov. 10, 2022, 9:46 a.m. UTC
From: Roberto Sassu <roberto.sassu@huawei.com> Rewrite security_old_inode_init_security() to call security_inode_init_security() before making changes to support multiple LSMs providing xattrs. Do it so that the required changes are done only in one place. Define the security_initxattrs() callback and pass it to security_inode_init_security() as argument, to obtain the first xattr provided by LSMs. This behavior is a bit different from the current one. Before this patch calling call_int_hook() could cause multiple LSMs to provide an xattr, since call_int_hook() does not stop when an LSM returns zero. The caller of security_old_inode_init_security() receives the last xattr set. The pointer of the xattr value of previous LSMs is lost, causing memory leaks. However, in practice, this scenario does not happen as the only in-tree LSMs providing an xattr at inode creation time are SELinux and Smack, which are mutually exclusive. Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> --- security/security.c | 58 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 10 deletions(-)
Comments
Hi Roberto, On Thu, 2022-11-10 at 10:46 +0100, Roberto Sassu wrote: > From: Roberto Sassu <roberto.sassu@huawei.com> > > Rewrite security_old_inode_init_security() to call > security_inode_init_security() before making changes to support multiple > LSMs providing xattrs. Do it so that the required changes are done only in > one place. Only security_inode_init_security() has support for EVM. Making security_old_inode_init_security() a wrapper for security_inode_init_security() could result in security.evm extended attributes being created that previously weren't created. In fact ocfs2 defines ocfs2_init_security_get() as a wrapper for both the old and new inode_init_security calls based on the caller's preference. Only mknod and symlink seem to use the old function. Wondering why do they differentiate between callers? (Cc'ing the ocfs2 mailing list as they're affected by this change.) "[PATCH v4 1/5] reiserfs: Add missing calls to reiserfs_security_free()" fixed a memory leak. I couldn't tell if there was a similar memory leak in ocfs2, the only other user of security_old_inode_init_security(). As ocfs2 already defines initxattrs, that leaves only reiserfs missing initxattrs(). A better, cleaner solution would be to define one. thanks, Mimi > > Define the security_initxattrs() callback and pass it to > security_inode_init_security() as argument, to obtain the first xattr > provided by LSMs. > > This behavior is a bit different from the current one. Before this patch > calling call_int_hook() could cause multiple LSMs to provide an xattr, > since call_int_hook() does not stop when an LSM returns zero. The caller of > security_old_inode_init_security() receives the last xattr set. The pointer > of the xattr value of previous LSMs is lost, causing memory leaks. > > However, in practice, this scenario does not happen as the only in-tree > LSMs providing an xattr at inode creation time are SELinux and Smack, which > are mutually exclusive. > > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>b
On 11/17/2022 2:03 PM, Mimi Zohar wrote: > Hi Roberto, > > On Thu, 2022-11-10 at 10:46 +0100, Roberto Sassu wrote: >> From: Roberto Sassu <roberto.sassu@huawei.com> >> >> Rewrite security_old_inode_init_security() to call >> security_inode_init_security() before making changes to support multiple >> LSMs providing xattrs. Do it so that the required changes are done only in >> one place. > > Only security_inode_init_security() has support for EVM. Making > security_old_inode_init_security() a wrapper for > security_inode_init_security() could result in security.evm extended > attributes being created that previously weren't created. Hi Mimi yes, I thought about this problem. In fact, it should not matter too much. Since security_old_inode_init_security() supports setting only one xattr: if there is an LSM xattr, that one will be set, and the EVM one will be discarded; if there is no LSM xattr, EVM would not add one. > In fact ocfs2 defines ocfs2_init_security_get() as a wrapper for both > the old and new inode_init_security calls based on the caller's > preference. Only mknod and symlink seem to use the old function. > Wondering why do they differentiate between callers? (Cc'ing the ocfs2 > mailing list as they're affected by this change.) > > "[PATCH v4 1/5] reiserfs: Add missing calls to > reiserfs_security_free()" fixed a memory leak. I couldn't tell if > there was a similar memory leak in ocfs2, the only other user of > security_old_inode_init_security(). Will look into it. > As ocfs2 already defines initxattrs, that leaves only reiserfs missing > initxattrs(). A better, cleaner solution would be to define one. Yes, great idea! Thanks Roberto > thanks, > > Mimi > >> >> Define the security_initxattrs() callback and pass it to >> security_inode_init_security() as argument, to obtain the first xattr >> provided by LSMs. >> >> This behavior is a bit different from the current one. Before this patch >> calling call_int_hook() could cause multiple LSMs to provide an xattr, >> since call_int_hook() does not stop when an LSM returns zero. The caller of >> security_old_inode_init_security() receives the last xattr set. The pointer >> of the xattr value of previous LSMs is lost, causing memory leaks. >> >> However, in practice, this scenario does not happen as the only in-tree >> LSMs providing an xattr at inode creation time are SELinux and Smack, which >> are mutually exclusive. >> >> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>b
On Thu, 2022-11-17 at 08:03 -0500, Mimi Zohar wrote: > Hi Roberto, > > On Thu, 2022-11-10 at 10:46 +0100, Roberto Sassu wrote: > > From: Roberto Sassu <roberto.sassu@huawei.com> > > > > Rewrite security_old_inode_init_security() to call > > security_inode_init_security() before making changes to support multiple > > LSMs providing xattrs. Do it so that the required changes are done only in > > one place. > > Only security_inode_init_security() has support for EVM. Making > security_old_inode_init_security() a wrapper for > security_inode_init_security() could result in security.evm extended > attributes being created that previously weren't created. > > In fact ocfs2 defines ocfs2_init_security_get() as a wrapper for both > the old and new inode_init_security calls based on the caller's > preference. Only mknod and symlink seem to use the old function. > Wondering why do they differentiate between callers? (Cc'ing the ocfs2 > mailing list as they're affected by this change.) > > "[PATCH v4 1/5] reiserfs: Add missing calls to > reiserfs_security_free()" fixed a memory leak. I couldn't tell if > there was a similar memory leak in ocfs2, the only other user of > security_old_inode_init_security(). From what I see, there is no memory leak there. > As ocfs2 already defines initxattrs, that leaves only reiserfs missing > initxattrs(). A better, cleaner solution would be to define one. If I understood why security_old_inode_init_security() is called instead of security_inode_init_security(), the reason seems that the filesystem code uses the length of the obtained xattr to make some calculations (e.g. reserve space). The xattr is written at a later time. Since for reiserfs there is a plan to deprecate it, it probably wouldn't be worth to support the creation of multiple xattrs. I would define a callback to take the first xattr and make a copy, so that calling security_inode_init_security() + reiserfs_initxattrs() is equivalent to calling security_old_inode_init_security(). But then, this is what anyway I was doing with the security_initxattrs() callback, for all callers of security_old_inode_i nit_security(). Also, security_old_inode_init_security() is exported to kernel modules. Maybe, it is used somewhere. So, unless we plan to remove it completely, it should be probably be fixed to avoid multiple LSMs successfully setting an xattr, and losing the memory of all except the last (which this patch fixes by calling security_inode_init_security()) . If there is still the preference, I will implement the reiserfs callback and make a fix for security_old_inode_init_security(). Thanks Roberto > thanks, > > Mimi > > > Define the security_initxattrs() callback and pass it to > > security_inode_init_security() as argument, to obtain the first xattr > > provided by LSMs. > > > > This behavior is a bit different from the current one. Before this patch > > calling call_int_hook() could cause multiple LSMs to provide an xattr, > > since call_int_hook() does not stop when an LSM returns zero. The caller of > > security_old_inode_init_security() receives the last xattr set. The pointer > > of the xattr value of previous LSMs is lost, causing memory leaks. > > > > However, in practice, this scenario does not happen as the only in-tree > > LSMs providing an xattr at inode creation time are SELinux and Smack, which > > are mutually exclusive. > > > > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>b
On Mon, 2022-11-21 at 10:45 +0100, Roberto Sassu wrote: > > As ocfs2 already defines initxattrs, that leaves only reiserfs missing > > initxattrs(). A better, cleaner solution would be to define one. > > If I understood why security_old_inode_init_security() is called > instead of security_inode_init_security(), the reason seems that the > filesystem code uses the length of the obtained xattr to make some > calculations (e.g. reserve space). The xattr is written at a later > time. > > Since for reiserfs there is a plan to deprecate it, it probably > wouldn't be worth to support the creation of multiple xattrs. I would > define a callback to take the first xattr and make a copy, so that > calling security_inode_init_security() + reiserfs_initxattrs() is > equivalent to calling security_old_inode_init_security(). > > But then, this is what anyway I was doing with the > security_initxattrs() callback, for all callers of security_old_inode_i > nit_security(). > > Also, security_old_inode_init_security() is exported to kernel modules. > Maybe, it is used somewhere. So, unless we plan to remove it > completely, it should be probably be fixed to avoid multiple LSMs > successfully setting an xattr, and losing the memory of all except the > last (which this patch fixes by calling security_inode_init_security()) > . > > If there is still the preference, I will implement the reiserfs > callback and make a fix for security_old_inode_init_security(). There's no sense in doing both, as the purpose of defining a reiserfs initxattrs function was to clean up this code making it more readable. Mimi
On Mon, Nov 21, 2022 at 3:54 PM Mimi Zohar <zohar@linux.ibm.com> wrote: > > On Mon, 2022-11-21 at 10:45 +0100, Roberto Sassu wrote: > > > As ocfs2 already defines initxattrs, that leaves only reiserfs missing > > > initxattrs(). A better, cleaner solution would be to define one. > > > > If I understood why security_old_inode_init_security() is called > > instead of security_inode_init_security(), the reason seems that the > > filesystem code uses the length of the obtained xattr to make some > > calculations (e.g. reserve space). The xattr is written at a later > > time. > > > > Since for reiserfs there is a plan to deprecate it, it probably > > wouldn't be worth to support the creation of multiple xattrs. I would > > define a callback to take the first xattr and make a copy, so that > > calling security_inode_init_security() + reiserfs_initxattrs() is > > equivalent to calling security_old_inode_init_security(). FWIW, reiserfs isn't going to be removed until 2025, I'm hopeful we can remove the IMA/EVM special cases before then :) > > But then, this is what anyway I was doing with the > > security_initxattrs() callback, for all callers of security_old_inode_i > > nit_security(). > > > > Also, security_old_inode_init_security() is exported to kernel modules. > > Maybe, it is used somewhere. So, unless we plan to remove it > > completely, it should be probably be fixed to avoid multiple LSMs > > successfully setting an xattr, and losing the memory of all except the > > last (which this patch fixes by calling security_inode_init_security()). I would much rather remove security_old_inode_init_security() then worry about what out-of-tree modules might be using it. Hopefully we can resolve the ocfs2 usage and get ocfs2 exclusively on the new hook without too much trouble, which means all we have left is reiserfs ... how difficult would you expect the conversion to be for reiserfs? > > If there is still the preference, I will implement the reiserfs > > callback and make a fix for security_old_inode_init_security(). > > There's no sense in doing both, as the purpose of defining a reiserfs > initxattrs function was to clean up this code making it more readable. > > Mimi
On Mon, 2022-11-21 at 18:55 -0500, Paul Moore wrote: > On Mon, Nov 21, 2022 at 3:54 PM Mimi Zohar <zohar@linux.ibm.com> wrote: > > On Mon, 2022-11-21 at 10:45 +0100, Roberto Sassu wrote: > > > > As ocfs2 already defines initxattrs, that leaves only reiserfs missing > > > > initxattrs(). A better, cleaner solution would be to define one. > > > > > > If I understood why security_old_inode_init_security() is called > > > instead of security_inode_init_security(), the reason seems that the > > > filesystem code uses the length of the obtained xattr to make some > > > calculations (e.g. reserve space). The xattr is written at a later > > > time. > > > > > > Since for reiserfs there is a plan to deprecate it, it probably > > > wouldn't be worth to support the creation of multiple xattrs. I would > > > define a callback to take the first xattr and make a copy, so that > > > calling security_inode_init_security() + reiserfs_initxattrs() is > > > equivalent to calling security_old_inode_init_security(). > > FWIW, reiserfs isn't going to be removed until 2025, I'm hopeful we > can remove the IMA/EVM special cases before then :) Well, we are not that far... > > > But then, this is what anyway I was doing with the > > > security_initxattrs() callback, for all callers of security_old_inode_i > > > nit_security(). > > > > > > Also, security_old_inode_init_security() is exported to kernel modules. > > > Maybe, it is used somewhere. So, unless we plan to remove it > > > completely, it should be probably be fixed to avoid multiple LSMs > > > successfully setting an xattr, and losing the memory of all except the > > > last (which this patch fixes by calling security_inode_init_security()). > > I would much rather remove security_old_inode_init_security() then > worry about what out-of-tree modules might be using it. Hopefully we > can resolve the ocfs2 usage and get ocfs2 exclusively on the new hook > without too much trouble, which means all we have left is reiserfs ... > how difficult would you expect the conversion to be for reiserfs? Ok for removing security_old_inode_init_security(). For reiserfs, I guess maintaining the current behavior of setting only one xattr should be easy. For multiple xattrs, I need to understand exactly how many blocks need to be reserved. > > > If there is still the preference, I will implement the reiserfs > > > callback and make a fix for security_old_inode_init_security(). > > > > There's no sense in doing both, as the purpose of defining a reiserfs > > initxattrs function was to clean up this code making it more readable. The fix for security_old_inode_init_security(), stopping at the first LSM returning zero, was to avoid the memory leak. Will not be needed if the function is removed. Roberto
diff --git a/security/security.c b/security/security.c index 79d82cb6e469..a0e9b4ce2341 100644 --- a/security/security.c +++ b/security/security.c @@ -1089,20 +1089,34 @@ int security_dentry_create_files_as(struct dentry *dentry, int mode, } EXPORT_SYMBOL(security_dentry_create_files_as); +static int security_initxattrs(struct inode *inode, const struct xattr *xattrs, + void *fs_info) +{ + struct xattr *dest = (struct xattr *)fs_info; + + dest->name = xattrs->name; + dest->value = xattrs->value; + dest->value_len = xattrs->value_len; + return 0; +} + int security_inode_init_security(struct inode *inode, struct inode *dir, const struct qstr *qstr, const initxattrs initxattrs, void *fs_data) { struct xattr new_xattrs[MAX_LSM_EVM_XATTR + 1]; struct xattr *lsm_xattr, *evm_xattr, *xattr; - int ret; + int ret = -EOPNOTSUPP; if (unlikely(IS_PRIVATE(inode))) - return 0; + goto out_exit; - if (!initxattrs) - return call_int_hook(inode_init_security, -EOPNOTSUPP, inode, - dir, qstr, NULL, NULL, NULL); + if (!initxattrs || + (initxattrs == &security_initxattrs && !fs_data)) { + ret = call_int_hook(inode_init_security, -EOPNOTSUPP, inode, + dir, qstr, NULL, NULL, NULL); + goto out_exit; + } memset(new_xattrs, 0, sizeof(new_xattrs)); lsm_xattr = new_xattrs; ret = call_int_hook(inode_init_security, -EOPNOTSUPP, inode, dir, qstr, @@ -1118,8 +1132,19 @@ int security_inode_init_security(struct inode *inode, struct inode *dir, goto out; ret = initxattrs(inode, new_xattrs, fs_data); out: - for (xattr = new_xattrs; xattr->value != NULL; xattr++) + for (xattr = new_xattrs; xattr->value != NULL; xattr++) { + /* + * Xattr value freed by the caller of + * security_old_inode_init_security(). + */ + if (xattr == new_xattrs && initxattrs == &security_initxattrs && + !ret) + continue; kfree(xattr->value); + } +out_exit: + if (initxattrs == &security_initxattrs) + return ret; return (ret == -EOPNOTSUPP) ? 0 : ret; } EXPORT_SYMBOL(security_inode_init_security); @@ -1136,10 +1161,23 @@ int security_old_inode_init_security(struct inode *inode, struct inode *dir, const struct qstr *qstr, const char **name, void **value, size_t *len) { - if (unlikely(IS_PRIVATE(inode))) - return -EOPNOTSUPP; - return call_int_hook(inode_init_security, -EOPNOTSUPP, inode, dir, - qstr, name, value, len); + struct xattr xattr = {}; + struct xattr *lsm_xattr = (value) ? &xattr : NULL; + int ret; + + ret = security_inode_init_security(inode, dir, qstr, + security_initxattrs, lsm_xattr); + if (ret) + return ret; + + if (name) + *name = lsm_xattr->name; + if (value) + *value = lsm_xattr->value; + if (len) + *len = lsm_xattr->value_len; + + return 0; } EXPORT_SYMBOL(security_old_inode_init_security);