From patchwork Fri Oct 28 16:49:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 13024047 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3B006ECAAA1 for ; Fri, 28 Oct 2022 16:50:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229740AbiJ1Quh (ORCPT ); Fri, 28 Oct 2022 12:50:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46834 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229520AbiJ1Qug (ORCPT ); Fri, 28 Oct 2022 12:50:36 -0400 Received: from frasgout11.his.huawei.com (frasgout11.his.huawei.com [14.137.139.23]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D8ACE31EE3; Fri, 28 Oct 2022 09:50:30 -0700 (PDT) Received: from mail02.huawei.com (unknown [172.18.147.227]) by frasgout11.his.huawei.com (SkyGuard) with ESMTP id 4MzT0126w3z9xqxd; Sat, 29 Oct 2022 00:44:01 +0800 (CST) Received: from huaweicloud.com (unknown [10.204.63.22]) by APP2 (Coremail) with SMTP id GxC2BwD3LPk3CFxjeW4cAA--.34547S2; Fri, 28 Oct 2022 17:50:11 +0100 (CET) From: Roberto Sassu 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, mykolal@fb.com, revest@chromium.org, jackmanb@chromium.org, shuah@kernel.org, paul@paul-moore.com, casey@schaufler-ca.com Cc: bpf@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC][PATCH 1/3] lsm: Clarify documentation of vm_enough_memory hook Date: Fri, 28 Oct 2022 18:49:46 +0200 Message-Id: <20221028164948.385783-1-roberto.sassu@huaweicloud.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-CM-TRANSID: GxC2BwD3LPk3CFxjeW4cAA--.34547S2 X-Coremail-Antispam: 1UD129KBjvdXoWruFy8GF18ZrWxtw17KrWUCFg_yoWkXFb_u3 4fG348Xw4fXF4xKa1Ikr93tryrK3yfXr1qgF1Yq39IqFWDJas5Gw4xWFnxX3WDWwn293s5 uFyktrWxAwnIgjkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8Yxn0WfASr-VFAUDa7-sFnT 9fnUUIcSsGvfJTRUUUbIAYFVCjjxCrM7AC8VAFwI0_Xr0_Wr1l1xkIjI8I6I8E6xAIw20E Y4v20xvaj40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwV A0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVWUJVWUCwA2z4x0Y4vE2Ix0cI8IcVCY1x02 67AKxVW8JVWxJwA2z4x0Y4vEx4A2jsIE14v26r4j6F4UM28EF7xvwVC2z280aVCY1x0267 AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40E x7xfMcIj6xIIjxv20xvE14v26r1j6r18McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x 0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lFIxGxcIEc7CjxVA2Y2ka0xkIwI1lc7CjxVAa w2AFwI0_GFv_Wryl42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxV Aqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r4a 6rW5MIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6x kF7I0E14v26r4j6F4UMIIF0xvE42xK8VAvwI8IcIk0rVWrJr0_WFyUJwCI42IY6I8E87Iv 67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyT uYvjxUIa0PDUUUU X-CM-SenderInfo: purev21wro2thvvxqx5xdzvxpfor3voofrz/1tbiAQATBF1jj4TMTQAAsi X-CFilter-Loop: Reflected Precedence: bulk List-ID: From: Roberto Sassu include/linux/lsm_hooks.h reports the result of the LSM infrastructure to the callers, not what LSMs should return to the LSM infrastructure. Clarify that and add that returning 1 from the LSMs means calling __vm_enough_memory() with cap_sys_admin set, 0 without. Signed-off-by: Roberto Sassu --- include/linux/lsm_hooks.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 4ec80b96c22e..f40b82ca91e7 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1411,7 +1411,9 @@ * Check permissions for allocating a new virtual mapping. * @mm contains the mm struct it is being added to. * @pages contains the number of pages. - * Return 0 if permission is granted. + * Return 0 if permission is granted by LSMs to the caller. LSMs should + * return 1 if __vm_enough_memory() should be called with + * cap_sys_admin set, 0 if not. * * @ismaclabel: * Check if the extended attribute specified by @name From patchwork Fri Oct 28 16:49:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 13024048 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF79CECAAA1 for ; Fri, 28 Oct 2022 16:50:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230094AbiJ1Qur (ORCPT ); Fri, 28 Oct 2022 12:50:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47464 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229971AbiJ1Quo (ORCPT ); Fri, 28 Oct 2022 12:50:44 -0400 Received: from frasgout11.his.huawei.com (frasgout11.his.huawei.com [14.137.139.23]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B506C82619; Fri, 28 Oct 2022 09:50:40 -0700 (PDT) Received: from mail02.huawei.com (unknown [172.18.147.229]) by frasgout11.his.huawei.com (SkyGuard) with ESMTP id 4MzT0B6J90z9xqxc; Sat, 29 Oct 2022 00:44:10 +0800 (CST) Received: from huaweicloud.com (unknown [10.204.63.22]) by APP2 (Coremail) with SMTP id GxC2BwD3LPk3CFxjeW4cAA--.34547S3; Fri, 28 Oct 2022 17:50:21 +0100 (CET) From: Roberto Sassu 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, mykolal@fb.com, revest@chromium.org, jackmanb@chromium.org, shuah@kernel.org, paul@paul-moore.com, casey@schaufler-ca.com Cc: bpf@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC][PATCH 2/3] bpf-lsm: Limit values that can be returned by security modules Date: Fri, 28 Oct 2022 18:49:47 +0200 Message-Id: <20221028164948.385783-2-roberto.sassu@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221028164948.385783-1-roberto.sassu@huaweicloud.com> References: <20221028164948.385783-1-roberto.sassu@huaweicloud.com> MIME-Version: 1.0 X-CM-TRANSID: GxC2BwD3LPk3CFxjeW4cAA--.34547S3 X-Coremail-Antispam: 1UD129KBjvJXoW3Xw4rCr15ur1rGFWxAw4DXFb_yoW3Cw4Upr 4xJFyYkrsYvrZIqa4Iyan5Zws5AF1Fga1DKr1DGr1IkrWIvrykJw1UAr1jqr9xWryUGrsa gr4qvF4Yg347ZaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUP2b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUGw A2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxS w2x7M28EF7xvwVC0I7IYx2IY67AKxVWUJVWUCwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxV W8JVWxJwA2z4x0Y4vEx4A2jsIE14v26r4j6F4UM28EF7xvwVC2z280aVCY1x0267AKxVW8 Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMc Ij6xIIjxv20xvE14v26r1j6r18McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_ Jr0_Gr1lF7xvr2IYc2Ij64vIr41lFIxGxcIEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI 0_GFv_Wryl42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG 67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r4a6rW5MI IYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E 14v26r4j6F4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJV W8JwCI42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7IU04q 2tUUUUU== X-CM-SenderInfo: purev21wro2thvvxqx5xdzvxpfor3voofrz/1tbiAQATBF1jj4TMTQABsj X-CFilter-Loop: Reflected Precedence: bulk List-ID: From: Roberto Sassu BPF LSM defines a bpf_lsm_*() function for each LSM hook, so that security modules can define their own implementation for the desired hooks. Unfortunately, BPF LSM does not restrict which values security modules can return (for non-void LSM hooks). Security modules might follow the conventions stated in include/linux/lsm_hooks.h, or put arbitrary values. This could cause big troubles, as the kernel is not ready to handle possibly malicious return values from LSMs. Until now, it was not the case, as each LSM is carefully reviewed and it won't be accepted if it does not meet the return value conventions. The biggest problem is when an LSM returns a positive value, instead of a negative value, as it could be converted to a pointer. Since such pointer escapes the IS_ERR() check, its use later in the code can cause unpredictable consequences (e.g. invalid memory access). Another problem is returning zero when an LSM is supposed to have done some operations. For example, the inode_init_security hook expects that their implementations return zero only if they set the name and value of the new xattr to be added to the new inode. Otherwise, other kernel subsystems might encounter unexpected conditions leading to a crash (e.g. evm_protected_xattr_common() getting NULL as argument). Finally, there are LSM hooks which are supposed to return just one as positive value, or non-negative values. Also in these cases, although it seems less critical, it is safer to return to callers of the LSM infrastructure more precisely what they expect. As eBPF allows code outside the kernel to run, it is its responsibility to ensure that only expected values are returned to LSM infrastructure callers. Create four new BTF ID sets, respectively for hooks that can return positive values, only one as positive value, that cannot return zero, and that cannot return negative values. Create also corresponding functions to check if the hook a security module is attached to belongs to one of the defined sets. Finally, check in the eBPF verifier the value returned by security modules for each attached LSM hook, and return -EINVAL (the security module cannot run) if the hook implementation does not satisfy the hook return value policy. Cc: stable@vger.kernel.org Fixes: 9d3fdea789c8 ("bpf: lsm: Provide attachment points for BPF LSM programs") Signed-off-by: Roberto Sassu --- include/linux/bpf_lsm.h | 24 ++++++++++++++++++ kernel/bpf/bpf_lsm.c | 56 +++++++++++++++++++++++++++++++++++++++++ kernel/bpf/verifier.c | 35 +++++++++++++++++++++++--- 3 files changed, 112 insertions(+), 3 deletions(-) diff --git a/include/linux/bpf_lsm.h b/include/linux/bpf_lsm.h index 4bcf76a9bb06..cd38aca4cfc0 100644 --- a/include/linux/bpf_lsm.h +++ b/include/linux/bpf_lsm.h @@ -28,6 +28,10 @@ int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog, const struct bpf_prog *prog); bool bpf_lsm_is_sleepable_hook(u32 btf_id); +bool bpf_lsm_can_ret_pos_value(u32 btf_id); +bool bpf_lsm_can_ret_only_one_as_pos_value(u32 btf_id); +bool bpf_lsm_cannot_ret_zero(u32 btf_id); +bool bpf_lsm_cannot_ret_neg_value(u32 btf_id); static inline struct bpf_storage_blob *bpf_inode( const struct inode *inode) @@ -51,6 +55,26 @@ static inline bool bpf_lsm_is_sleepable_hook(u32 btf_id) return false; } +static inline bool bpf_lsm_can_ret_pos_value(u32 btf_id) +{ + return false; +} + +static inline bool bpf_lsm_can_ret_only_one_as_pos_value(u32 btf_id) +{ + return false; +} + +static inline bool bpf_lsm_cannot_ret_zero(u32 btf_id) +{ + return false; +} + +static inline bool bpf_lsm_cannot_ret_neg_value(u32 btf_id) +{ + return false; +} + static inline int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog, const struct bpf_prog *prog) { diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c index d6c9b3705f24..3dcb70b2f978 100644 --- a/kernel/bpf/bpf_lsm.c +++ b/kernel/bpf/bpf_lsm.c @@ -348,6 +348,62 @@ bool bpf_lsm_is_sleepable_hook(u32 btf_id) return btf_id_set_contains(&sleepable_lsm_hooks, btf_id); } +/* The set of hooks which are allowed to return a positive value. */ +BTF_SET_START(pos_ret_value_lsm_hooks) +BTF_ID(func, bpf_lsm_vm_enough_memory) +BTF_ID(func, bpf_lsm_inode_getsecurity) +BTF_ID(func, bpf_lsm_inode_listsecurity) +BTF_ID(func, bpf_lsm_inode_need_killpriv) +BTF_ID(func, bpf_lsm_inode_copy_up_xattr) +BTF_ID(func, bpf_lsm_getprocattr) +BTF_ID(func, bpf_lsm_setprocattr) +BTF_ID(func, bpf_lsm_xfrm_state_pol_flow_match) +BTF_ID(func, bpf_lsm_key_getsecurity) +BTF_ID(func, bpf_lsm_ismaclabel) +BTF_ID(func, bpf_lsm_audit_rule_known) +BTF_ID(func, bpf_lsm_audit_rule_match) +BTF_SET_END(pos_ret_value_lsm_hooks) + +bool bpf_lsm_can_ret_pos_value(u32 btf_id) +{ + return btf_id_set_contains(&pos_ret_value_lsm_hooks, btf_id); +} + +BTF_SET_START(one_ret_value_lsm_hooks) +BTF_ID(func, bpf_lsm_vm_enough_memory) +BTF_ID(func, bpf_lsm_inode_copy_up_xattr) +BTF_ID(func, bpf_lsm_xfrm_state_pol_flow_match) +BTF_ID(func, bpf_lsm_ismaclabel) +BTF_ID(func, bpf_lsm_audit_rule_known) +BTF_ID(func, bpf_lsm_audit_rule_match) +BTF_SET_END(one_ret_value_lsm_hooks) + +bool bpf_lsm_can_ret_only_one_as_pos_value(u32 btf_id) +{ + return btf_id_set_contains(&one_ret_value_lsm_hooks, btf_id); +} + +/* The set of hooks which are not allowed to return zero. */ +BTF_SET_START(not_zero_ret_value_lsm_hooks) +BTF_ID(func, bpf_lsm_inode_init_security) +BTF_SET_END(not_zero_ret_value_lsm_hooks) + +bool bpf_lsm_cannot_ret_zero(u32 btf_id) +{ + return btf_id_set_contains(¬_zero_ret_value_lsm_hooks, btf_id); +} + +/* The set of hooks which are not allowed to return a negative value. */ +BTF_SET_START(not_neg_ret_value_lsm_hooks) +BTF_ID(func, bpf_lsm_vm_enough_memory) +BTF_ID(func, bpf_lsm_audit_rule_known) +BTF_SET_END(not_neg_ret_value_lsm_hooks) + +bool bpf_lsm_cannot_ret_neg_value(u32 btf_id) +{ + return btf_id_set_contains(¬_neg_ret_value_lsm_hooks, btf_id); +} + const struct bpf_prog_ops lsm_prog_ops = { }; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 8f849a763b79..7ee639b9f0e2 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -10622,9 +10622,38 @@ static int check_return_code(struct bpf_verifier_env *env) case BPF_PROG_TYPE_LSM: if (env->prog->expected_attach_type != BPF_LSM_CGROUP) { - /* Regular BPF_PROG_TYPE_LSM programs can return - * any value. - */ + /* < 0 */ + if (tnum_in(tnum_range((u64)(~0) << 31, (u64)(~0)), reg->var_off)) { + if (bpf_lsm_cannot_ret_neg_value(env->prog->aux->attach_btf_id)) { + verbose(env, "Invalid R0, cannot return negative value\n"); + return -EINVAL; + } + /* = 0 */ + } else if (tnum_equals_const(reg->var_off, 0)) { + if (bpf_lsm_cannot_ret_zero(env->prog->aux->attach_btf_id)) { + verbose(env, "Invalid R0, cannot return zero value\n"); + return -EINVAL; + } + /* = 1 */ + } else if (tnum_equals_const(reg->var_off, 1)) { + if (!bpf_lsm_can_ret_pos_value(env->prog->aux->attach_btf_id)) { + verbose(env, "Invalid R0, cannot return positive value\n"); + return -EINVAL; + } + /* > 1 */ + } else { + if (!bpf_lsm_can_ret_pos_value(env->prog->aux->attach_btf_id)) { + verbose(env, "Invalid R0, cannot return positive value\n"); + return -EINVAL; + } + + if (bpf_lsm_can_ret_only_one_as_pos_value(env->prog->aux->attach_btf_id)) { + verbose(env, + "Invalid R0, can return only one as positive value\n"); + return -EINVAL; + } + } + return 0; } if (!env->prog->aux->attach_func_proto->type) { From patchwork Fri Oct 28 16:49:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 13024049 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C32DFA3743 for ; Fri, 28 Oct 2022 16:51:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230018AbiJ1QvG (ORCPT ); Fri, 28 Oct 2022 12:51:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48994 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230077AbiJ1QvB (ORCPT ); Fri, 28 Oct 2022 12:51:01 -0400 Received: from frasgout11.his.huawei.com (frasgout11.his.huawei.com [14.137.139.23]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C82EC82619; Fri, 28 Oct 2022 09:50:49 -0700 (PDT) Received: from mail02.huawei.com (unknown [172.18.147.228]) by frasgout11.his.huawei.com (SkyGuard) with ESMTP id 4MzT0N1hMDz9xqxV; Sat, 29 Oct 2022 00:44:20 +0800 (CST) Received: from huaweicloud.com (unknown [10.204.63.22]) by APP2 (Coremail) with SMTP id GxC2BwD3LPk3CFxjeW4cAA--.34547S4; Fri, 28 Oct 2022 17:50:30 +0100 (CET) From: Roberto Sassu 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, mykolal@fb.com, revest@chromium.org, jackmanb@chromium.org, shuah@kernel.org, paul@paul-moore.com, casey@schaufler-ca.com Cc: bpf@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC][PATCH 3/3] selftests/bpf: Check if return values of LSM programs are allowed Date: Fri, 28 Oct 2022 18:49:48 +0200 Message-Id: <20221028164948.385783-3-roberto.sassu@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221028164948.385783-1-roberto.sassu@huaweicloud.com> References: <20221028164948.385783-1-roberto.sassu@huaweicloud.com> MIME-Version: 1.0 X-CM-TRANSID: GxC2BwD3LPk3CFxjeW4cAA--.34547S4 X-Coremail-Antispam: 1UD129KBjvJXoWxJF1kAr4UAFyxAr48Cr17ZFb_yoWrZw1Dp3 WrZw1jkF40vF4avFWrK397uayS9FW7CrW5KwnxZwnrZa97JF4xW3W5tFy5Zr13Gr15Gr9Y qr17Can5u3WUZa7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUPab4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUXw A2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxS w2x7M28EF7xvwVC0I7IYx2IY67AKxVWUJVWUCwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxV WxJVW8Jr1l84ACjcxK6I8E87Iv67AKxVW8JVWxJwA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_ Gr1j6F4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ew Av7VC0I7IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY 6r1j6r4UM4x0Y48IcxkI7VAKI48JM4IIrI8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14 v26r4a6rW5MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8C rVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXw CIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x02 67AKxVWxJVW8Jr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r 1j6r4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuYvjxU IID7DUUUU X-CM-SenderInfo: purev21wro2thvvxqx5xdzvxpfor3voofrz/1tbiAgATBF1jj4DNhQAAss X-CFilter-Loop: Reflected Precedence: bulk List-ID: From: Roberto Sassu Ensure that the eBPF verifier allows to load only LSM programs that return an allowed value depending on the LSM hook they attach to. Signed-off-by: Roberto Sassu --- .../testing/selftests/bpf/verifier/lsm_ret.c | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 tools/testing/selftests/bpf/verifier/lsm_ret.c diff --git a/tools/testing/selftests/bpf/verifier/lsm_ret.c b/tools/testing/selftests/bpf/verifier/lsm_ret.c new file mode 100644 index 000000000000..1a11f47fb24a --- /dev/null +++ b/tools/testing/selftests/bpf/verifier/lsm_ret.c @@ -0,0 +1,148 @@ +{ + "lsm return value: positive not allowed, return -EPERM", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, -EPERM), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_LSM, + .kfunc = "inode_permission", + .expected_attach_type = BPF_LSM_MAC, + .result = ACCEPT, +}, +{ + "lsm return value: positive not allowed, return zero", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_LSM, + .kfunc = "inode_permission", + .expected_attach_type = BPF_LSM_MAC, + .result = ACCEPT, +}, +{ + "lsm return value: positive not allowed, return one", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_LSM, + .kfunc = "inode_permission", + .expected_attach_type = BPF_LSM_MAC, + .errstr = "Invalid R0, cannot return positive value", + .result = REJECT, +}, +{ + "lsm return value: zero/positive not allowed, return -EPERM", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, -EPERM), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_LSM, + .kfunc = "inode_init_security", + .expected_attach_type = BPF_LSM_MAC, + .result = ACCEPT, +}, +{ + "lsm return value: zero/positive not allowed, return zero", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_LSM, + .kfunc = "inode_init_security", + .expected_attach_type = BPF_LSM_MAC, + .errstr = "Invalid R0, cannot return zero value", + .result = REJECT, +}, +{ + "lsm return value: zero/positive not allowed, return one", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_LSM, + .kfunc = "inode_init_security", + .expected_attach_type = BPF_LSM_MAC, + .errstr = "Invalid R0, cannot return positive value", + .result = REJECT, +}, +{ + "lsm return value: positive allowed, return one", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_LSM, + .kfunc = "getprocattr", + .expected_attach_type = BPF_LSM_MAC, + .result = ACCEPT, +}, +{ + "lsm return value: positive allowed, return two", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 2), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_LSM, + .kfunc = "getprocattr", + .expected_attach_type = BPF_LSM_MAC, + .result = ACCEPT, +}, +{ + "lsm return value: only one allowed, return one", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_LSM, + .kfunc = "audit_rule_match", + .expected_attach_type = BPF_LSM_MAC, + .result = ACCEPT, +}, +{ + "lsm return value: only one allowed, return two", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 2), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_LSM, + .kfunc = "audit_rule_match", + .expected_attach_type = BPF_LSM_MAC, + .errstr = "Invalid R0, can return only one as positive value", + .result = REJECT, +}, +{ + "lsm return value: negative not allowed, return -EPERM", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, -EPERM), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_LSM, + .kfunc = "vm_enough_memory", + .expected_attach_type = BPF_LSM_MAC, + .errstr = "Invalid R0, cannot return negative value", + .result = REJECT, +}, +{ + "lsm return value: negative not allowed, return zero", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_LSM, + .kfunc = "vm_enough_memory", + .expected_attach_type = BPF_LSM_MAC, + .result = ACCEPT, +}, +{ + "lsm return value: negative not allowed, return one", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_LSM, + .kfunc = "vm_enough_memory", + .expected_attach_type = BPF_LSM_MAC, + .result = ACCEPT, +},