Re: [RFC v3 06/22] landlock: Add LSM hooks
On 19/10/2016 17:19, Thomas Graf wrote: > On 09/14/16 at 09:23am, Mickaël Salaün wrote: >> diff --git a/include/linux/bpf.h b/include/linux/bpf.h >> index 9aa01d9d3d80..36c3e482239c 100644 >> --- a/include/linux/bpf.h >> +++ b/include/linux/bpf.h >> @@ -85,6 +85,8 @@ enum bpf_arg_type { >> >> ARG_PTR_TO_CTX, /* pointer to context */ >> ARG_ANYTHING, /* any (initialized) argument is ok */ >> + >> +ARG_PTR_TO_STRUCT_FILE, /* pointer to struct file */ > > This should go into patch 7 I guess? Right, the ARG_PTR_* are only used by BPF helpers. > >> +void __init landlock_add_hooks(void) >> +{ >> +pr_info("landlock: Becoming ready for sandboxing\n"); >> +security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks)); >> +} > > Can we add the hooks when we load the first BPF program for a hook? That > would also allow to not make this conditional on a new config option > which all all distros have to enable anyway. We could either add hook by hook or all hooks at once when loading a BPF program for which its subtype match the hook type, but I'm not sure it is worth it. I'd like to enable this LSM by default but we should be able to disable it if needed, like most kernel features. > > I would really like to see this patch split into the LSM part which > allows running BPF progs at LSM and your specific sandboxing use case > which requires the new BPF helpers, new reg type, etc. > I'll try to split it as much as possible. signature.asc Description: OpenPGP digital signature
Re: [RFC v3 06/22] landlock: Add LSM hooks
On 19/10/2016 17:19, Thomas Graf wrote: > On 09/14/16 at 09:23am, Mickaël Salaün wrote: >> diff --git a/include/linux/bpf.h b/include/linux/bpf.h >> index 9aa01d9d3d80..36c3e482239c 100644 >> --- a/include/linux/bpf.h >> +++ b/include/linux/bpf.h >> @@ -85,6 +85,8 @@ enum bpf_arg_type { >> >> ARG_PTR_TO_CTX, /* pointer to context */ >> ARG_ANYTHING, /* any (initialized) argument is ok */ >> + >> +ARG_PTR_TO_STRUCT_FILE, /* pointer to struct file */ > > This should go into patch 7 I guess? Right, the ARG_PTR_* are only used by BPF helpers. > >> +void __init landlock_add_hooks(void) >> +{ >> +pr_info("landlock: Becoming ready for sandboxing\n"); >> +security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks)); >> +} > > Can we add the hooks when we load the first BPF program for a hook? That > would also allow to not make this conditional on a new config option > which all all distros have to enable anyway. We could either add hook by hook or all hooks at once when loading a BPF program for which its subtype match the hook type, but I'm not sure it is worth it. I'd like to enable this LSM by default but we should be able to disable it if needed, like most kernel features. > > I would really like to see this patch split into the LSM part which > allows running BPF progs at LSM and your specific sandboxing use case > which requires the new BPF helpers, new reg type, etc. > I'll try to split it as much as possible. signature.asc Description: OpenPGP digital signature
Re: [RFC v3 06/22] landlock: Add LSM hooks
On 09/14/16 at 09:23am, Mickaël Salaün wrote: > diff --git a/include/linux/bpf.h b/include/linux/bpf.h > index 9aa01d9d3d80..36c3e482239c 100644 > --- a/include/linux/bpf.h > +++ b/include/linux/bpf.h > @@ -85,6 +85,8 @@ enum bpf_arg_type { > > ARG_PTR_TO_CTX, /* pointer to context */ > ARG_ANYTHING, /* any (initialized) argument is ok */ > + > + ARG_PTR_TO_STRUCT_FILE, /* pointer to struct file */ This should go into patch 7 I guess? > +void __init landlock_add_hooks(void) > +{ > + pr_info("landlock: Becoming ready for sandboxing\n"); > + security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks)); > +} Can we add the hooks when we load the first BPF program for a hook? That would also allow to not make this conditional on a new config option which all all distros have to enable anyway. I would really like to see this patch split into the LSM part which allows running BPF progs at LSM and your specific sandboxing use case which requires the new BPF helpers, new reg type, etc.
Re: [RFC v3 06/22] landlock: Add LSM hooks
On 09/14/16 at 09:23am, Mickaël Salaün wrote: > diff --git a/include/linux/bpf.h b/include/linux/bpf.h > index 9aa01d9d3d80..36c3e482239c 100644 > --- a/include/linux/bpf.h > +++ b/include/linux/bpf.h > @@ -85,6 +85,8 @@ enum bpf_arg_type { > > ARG_PTR_TO_CTX, /* pointer to context */ > ARG_ANYTHING, /* any (initialized) argument is ok */ > + > + ARG_PTR_TO_STRUCT_FILE, /* pointer to struct file */ This should go into patch 7 I guess? > +void __init landlock_add_hooks(void) > +{ > + pr_info("landlock: Becoming ready for sandboxing\n"); > + security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks)); > +} Can we add the hooks when we load the first BPF program for a hook? That would also allow to not make this conditional on a new config option which all all distros have to enable anyway. I would really like to see this patch split into the LSM part which allows running BPF progs at LSM and your specific sandboxing use case which requires the new BPF helpers, new reg type, etc.
[RFC v3 06/22] landlock: Add LSM hooks
Add LSM hooks which can be used by userland through Landlock (eBPF) programs. This programs are limited to a whitelist of functions (cf. next commit). The eBPF program context is depicted by the struct landlock_data (cf. include/uapi/linux/bpf.h): * hook: LSM hook ID * origin: what triggered this Landlock program (syscall, dedicated seccomp return or interruption) * cookie: the 16-bit value from the seccomp filter that triggered this Landlock program * args[6]: array of some LSM hook arguments The LSM hook arguments can contain raw values as integers or (unleakable) pointers. The only way to use the pointers are to pass them to an eBPF function according to their types (e.g. the bpf_landlock_cmp_fs_beneath_with_struct_file function can use a struct file pointer). For each Landlock program, the subtype allows to specify for which LSM hook the program is dedicated thanks to the "id" field. The "origin" field must contains each triggers for which the Landlock program will be called (e.g. every syscall or/and seccomp filters returning RET_LANDLOCK). The "access" bitfield can be used to allow a program to access a specific feature from a Landlock hook (i.e. context value or function). The flag guarding this feature may only be enabled according to the capabilities of the process loading the program. For now, there is three hooks for file system access control: * file_open * file_permission * mmap_file Changes since v2: * use subtypes instead of dedicated eBPF program types for each hook (suggested by Alexei Starovoitov) * replace convert_ctx_access() with subtype check * use an array of Landlock program list instead of a single list * handle running Landlock programs without needing a seccomp filter * use, check and expose "origin" to Landlock programs * mask the unused struct cred * (suggested by Andy Lutomirski) Changes since v1: * revamp access control from a syscall-based to a LSM hooks-based * do not use audit cache * no race conditions by design * architecture agnostic * switch from cBPF to eBPF (suggested by Daniel Borkmann) * new BPF context Signed-off-by: Mickaël SalaünCc: Alexei Starovoitov Cc: Andy Lutomirski Cc: Daniel Borkmann Cc: David S. Miller Cc: James Morris Cc: Kees Cook Cc: Serge E. Hallyn Cc: Will Drewry Link: https://lkml.kernel.org/r/20160827205559.ga43...@ast-mbp.thefacebook.com Link: https://lkml.kernel.org/r/20160827180642.ga38...@ast-mbp.thefacebook.com Link: https://lkml.kernel.org/r/CALCETrUK1umtXMEXXKzMAccNQCVTPA8_XNDf01B5=gazujw...@mail.gmail.com Link: https://lkml.kernel.org/r/20160827204307.ga43...@ast-mbp.thefacebook.com --- include/linux/bpf.h| 5 + include/linux/lsm_hooks.h | 5 + include/uapi/linux/bpf.h | 37 kernel/bpf/syscall.c | 10 +- kernel/bpf/verifier.c | 6 ++ security/Makefile | 2 + security/landlock/Makefile | 3 + security/landlock/lsm.c| 222 + security/security.c| 1 + 9 files changed, 289 insertions(+), 2 deletions(-) create mode 100644 security/landlock/Makefile create mode 100644 security/landlock/lsm.c diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 9aa01d9d3d80..36c3e482239c 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -85,6 +85,8 @@ enum bpf_arg_type { ARG_PTR_TO_CTX, /* pointer to context */ ARG_ANYTHING, /* any (initialized) argument is ok */ + + ARG_PTR_TO_STRUCT_FILE, /* pointer to struct file */ }; /* type of values returned from helper functions */ @@ -143,6 +145,9 @@ enum bpf_reg_type { */ PTR_TO_PACKET, PTR_TO_PACKET_END, /* skb->data + headlen */ + + /* Landlock */ + PTR_TO_STRUCT_FILE, }; struct bpf_prog; diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 558adfa5c8a8..069af34301d4 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1933,5 +1933,10 @@ void __init loadpin_add_hooks(void); #else static inline void loadpin_add_hooks(void) { }; #endif +#ifdef CONFIG_SECURITY_LANDLOCK +extern void __init landlock_add_hooks(void); +#else +static inline void __init landlock_add_hooks(void) { } +#endif /* CONFIG_SECURITY_LANDLOCK */ #endif /* ! __LINUX_LSM_HOOKS_H */ diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 667b6ef3ff1e..ad87003fe892 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -108,6 +108,7 @@ enum bpf_prog_type { BPF_PROG_TYPE_XDP, BPF_PROG_TYPE_PERF_EVENT, BPF_PROG_TYPE_CGROUP_SOCKET, + BPF_PROG_TYPE_LANDLOCK, }; enum bpf_attach_type { @@ -528,6 +529,23 @@ struct xdp_md { __u32 data_end; }; +/* LSM hooks */ +enum landlock_hook_id { +
[RFC v3 06/22] landlock: Add LSM hooks
Add LSM hooks which can be used by userland through Landlock (eBPF) programs. This programs are limited to a whitelist of functions (cf. next commit). The eBPF program context is depicted by the struct landlock_data (cf. include/uapi/linux/bpf.h): * hook: LSM hook ID * origin: what triggered this Landlock program (syscall, dedicated seccomp return or interruption) * cookie: the 16-bit value from the seccomp filter that triggered this Landlock program * args[6]: array of some LSM hook arguments The LSM hook arguments can contain raw values as integers or (unleakable) pointers. The only way to use the pointers are to pass them to an eBPF function according to their types (e.g. the bpf_landlock_cmp_fs_beneath_with_struct_file function can use a struct file pointer). For each Landlock program, the subtype allows to specify for which LSM hook the program is dedicated thanks to the "id" field. The "origin" field must contains each triggers for which the Landlock program will be called (e.g. every syscall or/and seccomp filters returning RET_LANDLOCK). The "access" bitfield can be used to allow a program to access a specific feature from a Landlock hook (i.e. context value or function). The flag guarding this feature may only be enabled according to the capabilities of the process loading the program. For now, there is three hooks for file system access control: * file_open * file_permission * mmap_file Changes since v2: * use subtypes instead of dedicated eBPF program types for each hook (suggested by Alexei Starovoitov) * replace convert_ctx_access() with subtype check * use an array of Landlock program list instead of a single list * handle running Landlock programs without needing a seccomp filter * use, check and expose "origin" to Landlock programs * mask the unused struct cred * (suggested by Andy Lutomirski) Changes since v1: * revamp access control from a syscall-based to a LSM hooks-based * do not use audit cache * no race conditions by design * architecture agnostic * switch from cBPF to eBPF (suggested by Daniel Borkmann) * new BPF context Signed-off-by: Mickaël Salaün Cc: Alexei Starovoitov Cc: Andy Lutomirski Cc: Daniel Borkmann Cc: David S. Miller Cc: James Morris Cc: Kees Cook Cc: Serge E. Hallyn Cc: Will Drewry Link: https://lkml.kernel.org/r/20160827205559.ga43...@ast-mbp.thefacebook.com Link: https://lkml.kernel.org/r/20160827180642.ga38...@ast-mbp.thefacebook.com Link: https://lkml.kernel.org/r/CALCETrUK1umtXMEXXKzMAccNQCVTPA8_XNDf01B5=gazujw...@mail.gmail.com Link: https://lkml.kernel.org/r/20160827204307.ga43...@ast-mbp.thefacebook.com --- include/linux/bpf.h| 5 + include/linux/lsm_hooks.h | 5 + include/uapi/linux/bpf.h | 37 kernel/bpf/syscall.c | 10 +- kernel/bpf/verifier.c | 6 ++ security/Makefile | 2 + security/landlock/Makefile | 3 + security/landlock/lsm.c| 222 + security/security.c| 1 + 9 files changed, 289 insertions(+), 2 deletions(-) create mode 100644 security/landlock/Makefile create mode 100644 security/landlock/lsm.c diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 9aa01d9d3d80..36c3e482239c 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -85,6 +85,8 @@ enum bpf_arg_type { ARG_PTR_TO_CTX, /* pointer to context */ ARG_ANYTHING, /* any (initialized) argument is ok */ + + ARG_PTR_TO_STRUCT_FILE, /* pointer to struct file */ }; /* type of values returned from helper functions */ @@ -143,6 +145,9 @@ enum bpf_reg_type { */ PTR_TO_PACKET, PTR_TO_PACKET_END, /* skb->data + headlen */ + + /* Landlock */ + PTR_TO_STRUCT_FILE, }; struct bpf_prog; diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 558adfa5c8a8..069af34301d4 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1933,5 +1933,10 @@ void __init loadpin_add_hooks(void); #else static inline void loadpin_add_hooks(void) { }; #endif +#ifdef CONFIG_SECURITY_LANDLOCK +extern void __init landlock_add_hooks(void); +#else +static inline void __init landlock_add_hooks(void) { } +#endif /* CONFIG_SECURITY_LANDLOCK */ #endif /* ! __LINUX_LSM_HOOKS_H */ diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 667b6ef3ff1e..ad87003fe892 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -108,6 +108,7 @@ enum bpf_prog_type { BPF_PROG_TYPE_XDP, BPF_PROG_TYPE_PERF_EVENT, BPF_PROG_TYPE_CGROUP_SOCKET, + BPF_PROG_TYPE_LANDLOCK, }; enum bpf_attach_type { @@ -528,6 +529,23 @@ struct xdp_md { __u32 data_end; }; +/* LSM hooks */ +enum landlock_hook_id { + LANDLOCK_HOOK_UNSPEC, + LANDLOCK_HOOK_FILE_OPEN, + LANDLOCK_HOOK_FILE_PERMISSION, + LANDLOCK_HOOK_MMAP_FILE, +}; +#define _LANDLOCK_HOOK_LAST LANDLOCK_HOOK_MMAP_FILE + +/* Trigger