[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200211031208.e6osrcathampoog7@ast-mbp>
Date: Mon, 10 Feb 2020 19:12:10 -0800
From: Alexei Starovoitov <alexei.starovoitov@...il.com>
To: KP Singh <kpsingh@...omium.org>
Cc: linux-kernel@...r.kernel.org, bpf@...r.kernel.org,
linux-security-module@...r.kernel.org,
Brendan Jackman <jackmanb@...gle.com>,
Florent Revest <revest@...gle.com>,
Thomas Garnier <thgarnie@...gle.com>,
Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
James Morris <jmorris@...ei.org>,
Kees Cook <keescook@...omium.org>,
Thomas Garnier <thgarnie@...omium.org>,
Michael Halcrow <mhalcrow@...gle.com>,
Paul Turner <pjt@...gle.com>,
Brendan Gregg <brendan.d.gregg@...il.com>,
Jann Horn <jannh@...gle.com>,
Matthew Garrett <mjg59@...gle.com>,
Christian Brauner <christian@...uner.io>,
Mickaël Salaün <mic@...ikod.net>,
Florent Revest <revest@...omium.org>,
Brendan Jackman <jackmanb@...omium.org>,
"Serge E. Hallyn" <serge@...lyn.com>,
Mauro Carvalho Chehab <mchehab+samsung@...nel.org>,
"David S. Miller" <davem@...emloft.net>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
kernel-team@...com
Subject: Re: [PATCH bpf-next v3 04/10] bpf: lsm: Add mutable hooks list for
the BPF LSM
On Thu, Jan 23, 2020 at 07:24:34AM -0800, KP Singh wrote:
> +#define CALL_BPF_LSM_INT_HOOKS(FUNC, ...) ({ \
> + int _ret = 0; \
> + do { \
> + struct security_hook_list *P; \
> + int _idx; \
> + \
> + if (hlist_empty(&bpf_lsm_hook_heads.FUNC)) \
> + break; \
> + \
> + _idx = bpf_lsm_srcu_read_lock(); \
> + \
> + hlist_for_each_entry(P, \
> + &bpf_lsm_hook_heads.FUNC, list) { \
> + _ret = P->hook.FUNC(__VA_ARGS__); \
> + if (_ret && IS_ENABLED(CONFIG_SECURITY_BPF_ENFORCE)) \
> + break; \
> + } \
> + bpf_lsm_srcu_read_unlock(_idx); \
> + } while (0); \
> + IS_ENABLED(CONFIG_SECURITY_BPF_ENFORCE) ? _ret : 0; \
> +})
This extra CONFIG_SECURITY_BPF_ENFORCE doesn't make sense to me.
Why do all the work for bpf-lsm and ignore return code? Such framework already
exists. For audit only case the user could have kprobed security_*() in
security/security.c and had access to exactly the same data. There is no need
in any of these patches if audit the only use case.
Obviously bpf-lsm has to be capable of making go/no-go decision, so
my preference is to drop this extra kconfig knob.
I think the agreement seen in earlier comments in this thread that the prefered
choice is to always have bpf-based lsm to be equivalent to LSM_ORDER_LAST. In
such case how about using bpf-trampoline fexit logic instead?
Pros:
- no changes to security/ directory
- no changes to call_int_hook() macro
- patches 4, 5, 6 no longer necessary
- when security is off all security_*() hooks do single
if (hlist_empty(&bpf_lsm_hook_heads.FUNC)) check.
With patch 4 there will two such checks. Tiny perf penalty.
With fexit approach there will be no extra check.
- fexit approach is fast even on kernels compiled with retpoline, since
its using direct calls
Cons:
- bpf trampoline so far is x86 only and arm64 support is wip
By plugging into fexit I'm proposing to let bpf-lsm prog type modify return
value. Currently bpf-fexit prog type has read-only access to it. Adding write
access is a straightforward verifier change. The bpf progs from patch 9 will
still look exactly the same way:
SEC("lsm/file_mprotect")
int BPF_PROG(mprotect_audit, struct vm_area_struct *vma,
unsigned long reqprot, unsigned long prot) { ... }
The difference that libbpf will be finding btf_id of security_file_mprotect()
function and adding fexit trampoline to it instead of going via
security_list_options and its own lsm_hook_idx uapi. I think reusing existing
tracing facilities to attach and multiplex multiple programs is cleaner. More
code reuse. Unified testing of lsm and tracing, etc.
Powered by blists - more mailing lists