Message ID | 20221115175652.3836811-5-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 l7csp2867640wru; Tue, 15 Nov 2022 10:01:53 -0800 (PST) X-Google-Smtp-Source: AA0mqf7+A5QQ09esTLSg2OJOPsiUhMU+YBiddQod6Qm1WnRB3HJdGq/a9/vpNxeAWr6aSlxUaJrd X-Received: by 2002:aa7:8155:0:b0:572:725f:33e6 with SMTP id d21-20020aa78155000000b00572725f33e6mr3938822pfn.46.1668535313058; Tue, 15 Nov 2022 10:01:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668535313; cv=none; d=google.com; s=arc-20160816; b=s28saOyUnPzfdAHIYOqrkHqeUctk1G9vxOc/XSQXJZxOGjSICElSll5O/hPwDt/Dk1 2EvUkUzrY3aKnRa+DK3b6SB/3lza9tCNqvjcnl71VtgOiu78v5v4PQtCtwLwjTmApgSa RoS7XiMnidGqB+9nx+oaAIMmUhuTx4RtqL+G/IW20fZV/8poiWXv64YniFUOPOMBgd77 OhPVp0o2cTUIUWYiKK+YSm/k4zXlrvDq7dC00RqwgDLhMf/LegRYXCG/o/TdarLZjZKa jUVZBNfKJ39xDbZBfSlNn16aCvJopuihlY06qEwyTKigzQmpY7scp32MXj09Oo4iW8Sx AxsQ== 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=ydn70Bq/7ln5vBJ1d3lSailr+Qa+lfbqN7DnnEQOeM4=; b=gecRAvvuBwmGm4q+i6rfMwqLaFjDggaezNbpbCNrm6QEkElzPAZ+IsUMwN1j0kE7U/ jrkR8MB8uDOsJDUgK3k4FL1Nw9ukVv9i4XBMFiou4QoGzpzxFCPPi81eFvpOmSmvYnVG pDwxBxng4Tn+FcDRTZTsUN30U/jeQX44WixlbiI5USxVUr/TdWth6T7V1Fm4cB1Gp/dF 3YwuYp+9otlWFzeR4fkMP/51hlmFeArQ7OPOdHs1APaz9RcJkS5xy7rESEmK/9t3+DeR c6oNIRdNbry5SKYWKNYD20AqHgpKW/NIVuDheQDQ3nBHAmnC/SwwMHf63owCLwhjC3K0 PvHQ== 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 y186-20020a638ac3000000b00476c5113dcasi1592751pgd.284.2022.11.15.10.01.26; Tue, 15 Nov 2022 10:01:53 -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 S238395AbiKOR7J (ORCPT <rfc822;maxim.cournoyer@gmail.com> + 99 others); Tue, 15 Nov 2022 12:59:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50512 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231596AbiKOR6L (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 15 Nov 2022 12:58:11 -0500 Received: from frasgout13.his.huawei.com (frasgout13.his.huawei.com [14.137.139.46]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6E2692F3BE; Tue, 15 Nov 2022 09:58:10 -0800 (PST) Received: from mail02.huawei.com (unknown [172.18.147.228]) by frasgout13.his.huawei.com (SkyGuard) with ESMTP id 4NBYdS3q2Dz9xs6c; Wed, 16 Nov 2022 01:51:24 +0800 (CST) Received: from huaweicloud.com (unknown [10.204.63.22]) by APP1 (Coremail) with SMTP id LxC2BwCHcW7o0nNj73dpAA--.16599S6; Tue, 15 Nov 2022 18:57:46 +0100 (CET) From: Roberto Sassu <roberto.sassu@huaweicloud.com> To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yhs@fb.com, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, revest@chromium.org, jackmanb@chromium.org, paul@paul-moore.com, jmorris@namei.org, serge@hallyn.com Cc: bpf@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, Roberto Sassu <roberto.sassu@huawei.com> Subject: [RFC][PATCH 4/4] security: Enforce limitations on return values from LSMs Date: Tue, 15 Nov 2022 18:56:52 +0100 Message-Id: <20221115175652.3836811-5-roberto.sassu@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221115175652.3836811-1-roberto.sassu@huaweicloud.com> References: <20221115175652.3836811-1-roberto.sassu@huaweicloud.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID: LxC2BwCHcW7o0nNj73dpAA--.16599S6 X-Coremail-Antispam: 1UD129KBjvJXoWxZFykWF4kJF4UJF1xGw47XFb_yoW5Jw47pw 4akFy5KF4j9Fy7XFZ3tanxua1Sv3yrKr4DCrZxXw15Za98Jwn8J3W8tF15tF1rCry8t34Y gF4Ut3y5Cw4DG37anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUPlb4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVWUCVW8JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr0_Cr1l84ACjcxK6I8E87Iv6xkF7I0E 14v26r4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_JrI_JrylYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACI402YVCY1x02628vn2kIc2xKxwCY1x0262 kKe7AKxVW8ZVWrXwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s02 6c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_GF v_WrylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI42IY6xIIjxv20xvE c7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aV AFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZF pf9x07j7GYLUUUUU= X-CM-SenderInfo: purev21wro2thvvxqx5xdzvxpfor3voofrz/1tbiAgARBF1jj4F5bgAAsw 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?1749586084701684014?= X-GMAIL-MSGID: =?utf-8?q?1749586084701684014?= |
Series |
security: Ensure LSMs return expected values
|
|
Commit Message
Roberto Sassu
Nov. 15, 2022, 5:56 p.m. UTC
From: Roberto Sassu <roberto.sassu@huawei.com> LSMs should not be able to return arbitrary return values, as the callers of the LSM infrastructure might not be ready to handle unexpected values (e.g. positive values that are first converted to a pointer with ERR_PTR, and then evaluated with IS_ERR()). Modify call_int_hook() to call is_ret_value_allowed(), so that the return value from each LSM for a given hook is checked. If for the interval the return value falls into the corresponding flag is not set, change the return value to the default value, just for the current LSM. A misbehaving LSM would not have impact on the decision of other LSMs, as the loop terminates whenever the return value is not zero. Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> --- security/security.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
Comments
On Tue, Nov 15, 2022 at 12:58 PM Roberto Sassu <roberto.sassu@huaweicloud.com> wrote: > > From: Roberto Sassu <roberto.sassu@huawei.com> > > LSMs should not be able to return arbitrary return values, as the callers > of the LSM infrastructure might not be ready to handle unexpected values > (e.g. positive values that are first converted to a pointer with ERR_PTR, > and then evaluated with IS_ERR()). > > Modify call_int_hook() to call is_ret_value_allowed(), so that the return > value from each LSM for a given hook is checked. If for the interval the > return value falls into the corresponding flag is not set, change the > return value to the default value, just for the current LSM. > > A misbehaving LSM would not have impact on the decision of other LSMs, as > the loop terminates whenever the return value is not zero. > > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> > --- > security/security.c | 34 ++++++++++++++++++++++++++++++++++ > 1 file changed, 34 insertions(+) Casey touched on some of this in his reply to patch 0/4, but basically I see this as a BPF LSM specific problem and not a generalized LSM issue that should be addressed at the LSM layer. Especially if the solution involves incurring additional processing for every LSM hook instantiation, regardless if a BPF LSM is present. Reading your overall patchset description I believe that you understand this too. If you want to somehow instrument the LSM hook definitions (what I believe to be the motivation behind patch 3/4) to indicate valid return values for use by the BPF verifier, I think we could entertain that, or at least discuss it further, but I'm not inclined to support any runtime overhead at the LSM layer for a specific LSM.
On Tue, 2022-11-15 at 21:35 -0500, Paul Moore wrote: > On Tue, Nov 15, 2022 at 12:58 PM Roberto Sassu > <roberto.sassu@huaweicloud.com> wrote: > > From: Roberto Sassu <roberto.sassu@huawei.com> > > > > LSMs should not be able to return arbitrary return values, as the callers > > of the LSM infrastructure might not be ready to handle unexpected values > > (e.g. positive values that are first converted to a pointer with ERR_PTR, > > and then evaluated with IS_ERR()). > > > > Modify call_int_hook() to call is_ret_value_allowed(), so that the return > > value from each LSM for a given hook is checked. If for the interval the > > return value falls into the corresponding flag is not set, change the > > return value to the default value, just for the current LSM. > > > > A misbehaving LSM would not have impact on the decision of other LSMs, as > > the loop terminates whenever the return value is not zero. > > > > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> > > --- > > security/security.c | 34 ++++++++++++++++++++++++++++++++++ > > 1 file changed, 34 insertions(+) > > Casey touched on some of this in his reply to patch 0/4, but basically > I see this as a BPF LSM specific problem and not a generalized LSM > issue that should be addressed at the LSM layer. Especially if the > solution involves incurring additional processing for every LSM hook > instantiation, regardless if a BPF LSM is present. Reading your > overall patchset description I believe that you understand this too. Yes, I had this concern too. Thanks Paul and Casey for taking the time to reply. I liked the fact that the fix is extremely simple, but nevertheless it should not impact the performance, if there are alternative ways. I thought maybe we look at non-zero values, since the check is already there. But it could be that there is an impact for it too (maybe for audit_rule_match?). > If you want to somehow instrument the LSM hook definitions (what I > believe to be the motivation behind patch 3/4) to indicate valid > return values for use by the BPF verifier, I think we could entertain > that, or at least discuss it further, but I'm not inclined to support > any runtime overhead at the LSM layer for a specific LSM. Ok, yes. Patches 1-3 would help to keep in sync the LSM infrastructure and eBPF, but it is not strictly needed. I could propose an eBPF-only alternative to declare sets of functions per interval. More or less, I developed an eBPF-based alternative also for patch 4. It is just a proof of concept. Will propose it, to validate the idea. Thanks Roberto
On Wed, Nov 16, 2022 at 9:37 AM Roberto Sassu <roberto.sassu@huaweicloud.com> wrote: > On Tue, 2022-11-15 at 21:35 -0500, Paul Moore wrote: > > If you want to somehow instrument the LSM hook definitions (what I > > believe to be the motivation behind patch 3/4) to indicate valid > > return values for use by the BPF verifier, I think we could entertain > > that, or at least discuss it further, but I'm not inclined to support > > any runtime overhead at the LSM layer for a specific LSM. > > Ok, yes. Patches 1-3 would help to keep in sync the LSM infrastructure > and eBPF, but it is not strictly needed. I could propose an eBPF-only > alternative to declare sets of functions per interval. > > More or less, I developed an eBPF-based alternative also for patch 4. > It is just a proof of concept. Will propose it, to validate the idea. Thanks, I think that might be the best approach. Also, please resubmit patches 1/4 and 2/4 with those small changes; those are nice improvements that just need a couple of small tweaks to be acceptable :)
diff --git a/security/security.c b/security/security.c index 4041d24e3283..cd417a8a0e65 100644 --- a/security/security.c +++ b/security/security.c @@ -716,6 +716,35 @@ static int lsm_superblock_alloc(struct super_block *sb) #include <linux/lsm_hook_defs.h> #undef LSM_HOOK +/* + * The return value flags of the LSM hook are defined in linux/lsm_hook_defs.h + * and can be accessed with: + * + * LSM_RET_FLAGS(<hook_name>) + * + * The macros below define static constants for the return value flags of each + * LSM hook. + */ +#define LSM_RET_FLAGS(NAME) (NAME##_ret_flags) +#define DECLARE_LSM_RET_FLAGS(RET_FLAGS, NAME) \ + static const u32 __maybe_unused LSM_RET_FLAGS(NAME) = (RET_FLAGS); +#define LSM_HOOK(RET, DEFAULT, RET_FLAGS, NAME, ...) \ + DECLARE_LSM_RET_FLAGS(RET_FLAGS, NAME) + +#include <linux/lsm_hook_defs.h> +#undef LSM_HOOK + +static bool is_ret_value_allowed(int ret, u32 ret_flags) +{ + if ((ret < 0 && !(ret_flags & LSM_RET_NEG)) || + (ret == 0 && !(ret_flags & LSM_RET_ZERO)) || + (ret == 1 && !(ret_flags & LSM_RET_ONE)) || + (ret > 1 && !(ret_flags & LSM_RET_GT_ONE))) + return false; + + return true; +} + /* * Hook list operation macros. * @@ -741,6 +770,11 @@ static int lsm_superblock_alloc(struct super_block *sb) \ hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \ RC = P->hook.FUNC(__VA_ARGS__); \ + if (!is_ret_value_allowed(RC, LSM_RET_FLAGS(FUNC))) { \ + WARN_ONCE(1, "Illegal ret %d for " #FUNC " from %s, forcing %d\n", \ + RC, P->lsm, LSM_RET_DEFAULT(FUNC)); \ + RC = LSM_RET_DEFAULT(FUNC); \ + } \ if (RC != 0) \ break; \ } \