Message ID | 20191104172146.30797-5-mic@digikod.net (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Landlock LSM | expand |
On Mon, Nov 04, 2019 at 06:21:43PM +0100, Mickaël Salaün wrote: > Add a first Landlock hook that can be used to enforce a security policy > or to audit some process activities. For a sandboxing use-case, it is > needed to inform the kernel if a task can legitimately debug another. > ptrace(2) can also be used by an attacker to impersonate another task > and remain undetected while performing malicious activities. > > Using ptrace(2) and related features on a target process can lead to a > privilege escalation. A sandboxed task must then be able to tell the > kernel if another task is more privileged, via ptrace_may_access(). > > Signed-off-by: Mickaël Salaün <mic@digikod.net> ... > +static int check_ptrace(struct landlock_domain *domain, > + struct task_struct *tracer, struct task_struct *tracee) > +{ > + struct landlock_hook_ctx_ptrace ctx_ptrace = { > + .prog_ctx = { > + .tracer = (uintptr_t)tracer, > + .tracee = (uintptr_t)tracee, > + }, > + }; So you're passing two kernel pointers obfuscated as u64 into bpf program yet claiming that the end goal is to make landlock unprivileged?! The most basic security hole in the tool that is aiming to provide security. I think the only way bpf-based LSM can land is both landlock and KRSI developers work together on a design that solves all use cases. BPF is capable to be a superset of all existing LSMs whereas landlock and KRSI propsals today are custom solutions to specific security concerns. BPF subsystem was extended with custom things in the past. In networking we have lwt, skb, tc, xdp, sk program types with a lot of overlapping functionality. We couldn't figure out how to generalize them into single 'networking' program. Now we can and we should. Accepting two partially overlapping bpf-based LSMs would be repeating the same mistake again.
On 11/5/2019 9:18 AM, Alexei Starovoitov wrote: > On Mon, Nov 04, 2019 at 06:21:43PM +0100, Mickaël Salaün wrote: >> Add a first Landlock hook that can be used to enforce a security policy >> or to audit some process activities. For a sandboxing use-case, it is >> needed to inform the kernel if a task can legitimately debug another. >> ptrace(2) can also be used by an attacker to impersonate another task >> and remain undetected while performing malicious activities. >> >> Using ptrace(2) and related features on a target process can lead to a >> privilege escalation. A sandboxed task must then be able to tell the >> kernel if another task is more privileged, via ptrace_may_access(). >> >> Signed-off-by: Mickaël Salaün <mic@digikod.net> > ... >> +static int check_ptrace(struct landlock_domain *domain, >> + struct task_struct *tracer, struct task_struct *tracee) >> +{ >> + struct landlock_hook_ctx_ptrace ctx_ptrace = { >> + .prog_ctx = { >> + .tracer = (uintptr_t)tracer, >> + .tracee = (uintptr_t)tracee, >> + }, >> + }; > So you're passing two kernel pointers obfuscated as u64 into bpf program > yet claiming that the end goal is to make landlock unprivileged?! > The most basic security hole in the tool that is aiming to provide security. > > I think the only way bpf-based LSM can land is both landlock and KRSI > developers work together on a design that solves all use cases. BPF is capable > to be a superset of all existing LSMs I can't agree with this. Nope. There are many security models for which BPF introduces excessive complexity. You don't need or want the generality of a general purpose programming language to implement Smack or TOMOYO. Or a simple Bell & LaPadula for that matter. SELinux? I can't imagine anyone trying to do that in eBPF, although I'm willing to be surprised. Being able to enforce a policy isn't the only criteria for an LSM. It's got to perform well and integrate with the rest of the system. I see many issues with a BPF <-> vfs interface. > whereas landlock and KRSI propsals today > are custom solutions to specific security concerns. Yes. As they should be. No one has every solved the entire security problem, and no one ever will. The only hope we have to address security issues is to have the flexibility to add the mechanisms needed for the concerns of the day. Ideally, we should be able to drop mechanisms when we decide that they no longer add value. > BPF subsystem was extended > with custom things in the past. In networking we have lwt, skb, tc, xdp, sk > program types with a lot of overlapping functionality. We couldn't figure out > how to generalize them into single 'networking' program. Now we can and we > should. Accepting two partially overlapping bpf-based LSMs would be repeating > the same mistake again. I don't get your analogy at all. You have a variety of programs because you have a variety of protocols and administrative interfaces. Of course you don't have a single 'networking" program. Security has a variety of issues and policies. A single 'security' program makes no sense whatever.
On 05/11/2019 18:18, Alexei Starovoitov wrote: > On Mon, Nov 04, 2019 at 06:21:43PM +0100, Mickaël Salaün wrote: >> Add a first Landlock hook that can be used to enforce a security policy >> or to audit some process activities. For a sandboxing use-case, it is >> needed to inform the kernel if a task can legitimately debug another. >> ptrace(2) can also be used by an attacker to impersonate another task >> and remain undetected while performing malicious activities. >> >> Using ptrace(2) and related features on a target process can lead to a >> privilege escalation. A sandboxed task must then be able to tell the >> kernel if another task is more privileged, via ptrace_may_access(). >> >> Signed-off-by: Mickaël Salaün <mic@digikod.net> > ... >> +static int check_ptrace(struct landlock_domain *domain, >> + struct task_struct *tracer, struct task_struct *tracee) >> +{ >> + struct landlock_hook_ctx_ptrace ctx_ptrace = { >> + .prog_ctx = { >> + .tracer = (uintptr_t)tracer, >> + .tracee = (uintptr_t)tracee, >> + }, >> + }; > > So you're passing two kernel pointers obfuscated as u64 into bpf program > yet claiming that the end goal is to make landlock unprivileged?! > The most basic security hole in the tool that is aiming to provide security. How could you used these pointers without dedicated BPF helpers? This context items are typed as PTR_TO_TASK and can't be used without a dedicated helper able to deal with ARG_PTR_TO_TASK. Moreover, pointer arithmetic is explicitly forbidden (and I added tests for that). Did I miss something? > > I think the only way bpf-based LSM can land is both landlock and KRSI > developers work together on a design that solves all use cases. As I said in a previous cover letter [1], that would be great. I think that the current Landlock bases (almost everything from this series except the seccomp interface) should meet both needs, but I would like to have the point of view of the KRSI developers. [1] https://lore.kernel.org/lkml/20191029171505.6650-1-mic@digikod.net/ > BPF is capable > to be a superset of all existing LSMs whereas landlock and KRSI propsals today > are custom solutions to specific security concerns. BPF subsystem was extended > with custom things in the past. In networking we have lwt, skb, tc, xdp, sk > program types with a lot of overlapping functionality. We couldn't figure out > how to generalize them into single 'networking' program. Now we can and we > should. Accepting two partially overlapping bpf-based LSMs would be repeating > the same mistake again. I'll let the LSM maintainers comment on whether BPF could be a superset of all LSM, but given the complexity of an access-control system, I have some doubts though. Anyway, we need to start somewhere and then iterate. This patch series is a first step.
On Tue, Nov 05, 2019 at 09:55:42AM -0800, Casey Schaufler wrote: > On 11/5/2019 9:18 AM, Alexei Starovoitov wrote: > > On Mon, Nov 04, 2019 at 06:21:43PM +0100, Mickaël Salaün wrote: > >> Add a first Landlock hook that can be used to enforce a security policy > >> or to audit some process activities. For a sandboxing use-case, it is > >> needed to inform the kernel if a task can legitimately debug another. > >> ptrace(2) can also be used by an attacker to impersonate another task > >> and remain undetected while performing malicious activities. > >> > >> Using ptrace(2) and related features on a target process can lead to a > >> privilege escalation. A sandboxed task must then be able to tell the > >> kernel if another task is more privileged, via ptrace_may_access(). > >> > >> Signed-off-by: Mickaël Salaün <mic@digikod.net> > > ... > >> +static int check_ptrace(struct landlock_domain *domain, > >> + struct task_struct *tracer, struct task_struct *tracee) > >> +{ > >> + struct landlock_hook_ctx_ptrace ctx_ptrace = { > >> + .prog_ctx = { > >> + .tracer = (uintptr_t)tracer, > >> + .tracee = (uintptr_t)tracee, > >> + }, > >> + }; > > So you're passing two kernel pointers obfuscated as u64 into bpf program > > yet claiming that the end goal is to make landlock unprivileged?! > > The most basic security hole in the tool that is aiming to provide security. > > > > I think the only way bpf-based LSM can land is both landlock and KRSI > > developers work together on a design that solves all use cases. BPF is capable > > to be a superset of all existing LSMs > > I can't agree with this. Nope. There are many security models > for which BPF introduces excessive complexity. You don't need > or want the generality of a general purpose programming language > to implement Smack or TOMOYO. Or a simple Bell & LaPadula for > that matter. SELinux? I can't imagine anyone trying to do that > in eBPF, although I'm willing to be surprised. Being able to > enforce a policy isn't the only criteria for an LSM. what are the other criteria? > It's got > to perform well and integrate with the rest of the system. what do you mean by that? > I see many issues with a BPF <-> vfs interface. There is no such interface today. What do you have in mind? > the mechanisms needed for the concerns of the day. Ideally, > we should be able to drop mechanisms when we decide that they > no longer add value. Exactly. bpf-based lsm must not add to kernel abi.
On Tue, Nov 05, 2019 at 07:01:41PM +0100, Mickaël Salaün wrote: > > On 05/11/2019 18:18, Alexei Starovoitov wrote: > > On Mon, Nov 04, 2019 at 06:21:43PM +0100, Mickaël Salaün wrote: > >> Add a first Landlock hook that can be used to enforce a security policy > >> or to audit some process activities. For a sandboxing use-case, it is > >> needed to inform the kernel if a task can legitimately debug another. > >> ptrace(2) can also be used by an attacker to impersonate another task > >> and remain undetected while performing malicious activities. > >> > >> Using ptrace(2) and related features on a target process can lead to a > >> privilege escalation. A sandboxed task must then be able to tell the > >> kernel if another task is more privileged, via ptrace_may_access(). > >> > >> Signed-off-by: Mickaël Salaün <mic@digikod.net> > > ... > >> +static int check_ptrace(struct landlock_domain *domain, > >> + struct task_struct *tracer, struct task_struct *tracee) > >> +{ > >> + struct landlock_hook_ctx_ptrace ctx_ptrace = { > >> + .prog_ctx = { > >> + .tracer = (uintptr_t)tracer, > >> + .tracee = (uintptr_t)tracee, > >> + }, > >> + }; > > > > So you're passing two kernel pointers obfuscated as u64 into bpf program > > yet claiming that the end goal is to make landlock unprivileged?! > > The most basic security hole in the tool that is aiming to provide security. > > How could you used these pointers without dedicated BPF helpers? This > context items are typed as PTR_TO_TASK and can't be used without a > dedicated helper able to deal with ARG_PTR_TO_TASK. Moreover, pointer > arithmetic is explicitly forbidden (and I added tests for that). Did I > miss something? It's a pointer leak. > > > > > I think the only way bpf-based LSM can land is both landlock and KRSI > > developers work together on a design that solves all use cases. > > As I said in a previous cover letter [1], that would be great. I think > that the current Landlock bases (almost everything from this series > except the seccomp interface) should meet both needs, but I would like > to have the point of view of the KRSI developers. > > [1] https://lore.kernel.org/lkml/20191029171505.6650-1-mic@digikod.net/ > > > BPF is capable > > to be a superset of all existing LSMs whereas landlock and KRSI propsals today > > are custom solutions to specific security concerns. BPF subsystem was extended > > with custom things in the past. In networking we have lwt, skb, tc, xdp, sk > > program types with a lot of overlapping functionality. We couldn't figure out > > how to generalize them into single 'networking' program. Now we can and we > > should. Accepting two partially overlapping bpf-based LSMs would be repeating > > the same mistake again. > > I'll let the LSM maintainers comment on whether BPF could be a superset > of all LSM, but given the complexity of an access-control system, I have > some doubts though. Anyway, we need to start somewhere and then iterate. > This patch series is a first step. I would like KRSI folks to speak up. So far I don't see any sharing happening between landlock and KRSI. You're claiming this set is a first step. They're claiming the same about their patches. I'd like to set a patchset that was jointly developed.
On 11/5/2019 11:31 AM, Alexei Starovoitov wrote: > On Tue, Nov 05, 2019 at 09:55:42AM -0800, Casey Schaufler wrote: >> On 11/5/2019 9:18 AM, Alexei Starovoitov wrote: >>> On Mon, Nov 04, 2019 at 06:21:43PM +0100, Mickaël Salaün wrote: >>>> Add a first Landlock hook that can be used to enforce a security policy >>>> or to audit some process activities. For a sandboxing use-case, it is >>>> needed to inform the kernel if a task can legitimately debug another. >>>> ptrace(2) can also be used by an attacker to impersonate another task >>>> and remain undetected while performing malicious activities. >>>> >>>> Using ptrace(2) and related features on a target process can lead to a >>>> privilege escalation. A sandboxed task must then be able to tell the >>>> kernel if another task is more privileged, via ptrace_may_access(). >>>> >>>> Signed-off-by: Mickaël Salaün <mic@digikod.net> >>> ... >>>> +static int check_ptrace(struct landlock_domain *domain, >>>> + struct task_struct *tracer, struct task_struct *tracee) >>>> +{ >>>> + struct landlock_hook_ctx_ptrace ctx_ptrace = { >>>> + .prog_ctx = { >>>> + .tracer = (uintptr_t)tracer, >>>> + .tracee = (uintptr_t)tracee, >>>> + }, >>>> + }; >>> So you're passing two kernel pointers obfuscated as u64 into bpf program >>> yet claiming that the end goal is to make landlock unprivileged?! >>> The most basic security hole in the tool that is aiming to provide security. >>> >>> I think the only way bpf-based LSM can land is both landlock and KRSI >>> developers work together on a design that solves all use cases. BPF is capable >>> to be a superset of all existing LSMs >> I can't agree with this. Nope. There are many security models >> for which BPF introduces excessive complexity. You don't need >> or want the generality of a general purpose programming language >> to implement Smack or TOMOYO. Or a simple Bell & LaPadula for >> that matter. SELinux? I can't imagine anyone trying to do that >> in eBPF, although I'm willing to be surprised. Being able to >> enforce a policy isn't the only criteria for an LSM. > what are the other criteria? They include, but are not limited to, performance impact and the ability to be analyzed. The interactions with other subsystems meeting the requirements thereof is always a concern. > >> It's got >> to perform well and integrate with the rest of the system. > what do you mean by that? It has to be fast, or the networking people are going to have fits. You can't require the addition of a pointer into the skb because it'll get rejected out of hand. You can't completely refactor the vfs locking to accommodate you needs. > >> I see many issues with a BPF <-> vfs interface. > There is no such interface today. What do you have in mind? You can't implement SELinux or Smack using BPF without a way to manipulate inode data. > >> the mechanisms needed for the concerns of the day. Ideally, >> we should be able to drop mechanisms when we decide that they >> no longer add value. > Exactly. bpf-based lsm must not add to kernel abi. Huh? I have no idea where that came from.
On Tue, Nov 05, 2019 at 11:55:17AM -0800, Casey Schaufler wrote: > On 11/5/2019 11:31 AM, Alexei Starovoitov wrote: > > On Tue, Nov 05, 2019 at 09:55:42AM -0800, Casey Schaufler wrote: > >> On 11/5/2019 9:18 AM, Alexei Starovoitov wrote: > >>> On Mon, Nov 04, 2019 at 06:21:43PM +0100, Mickaël Salaün wrote: > >>>> Add a first Landlock hook that can be used to enforce a security policy > >>>> or to audit some process activities. For a sandboxing use-case, it is > >>>> needed to inform the kernel if a task can legitimately debug another. > >>>> ptrace(2) can also be used by an attacker to impersonate another task > >>>> and remain undetected while performing malicious activities. > >>>> > >>>> Using ptrace(2) and related features on a target process can lead to a > >>>> privilege escalation. A sandboxed task must then be able to tell the > >>>> kernel if another task is more privileged, via ptrace_may_access(). > >>>> > >>>> Signed-off-by: Mickaël Salaün <mic@digikod.net> > >>> ... > >>>> +static int check_ptrace(struct landlock_domain *domain, > >>>> + struct task_struct *tracer, struct task_struct *tracee) > >>>> +{ > >>>> + struct landlock_hook_ctx_ptrace ctx_ptrace = { > >>>> + .prog_ctx = { > >>>> + .tracer = (uintptr_t)tracer, > >>>> + .tracee = (uintptr_t)tracee, > >>>> + }, > >>>> + }; > >>> So you're passing two kernel pointers obfuscated as u64 into bpf program > >>> yet claiming that the end goal is to make landlock unprivileged?! > >>> The most basic security hole in the tool that is aiming to provide security. > >>> > >>> I think the only way bpf-based LSM can land is both landlock and KRSI > >>> developers work together on a design that solves all use cases. BPF is capable > >>> to be a superset of all existing LSMs > >> I can't agree with this. Nope. There are many security models > >> for which BPF introduces excessive complexity. You don't need > >> or want the generality of a general purpose programming language > >> to implement Smack or TOMOYO. Or a simple Bell & LaPadula for > >> that matter. SELinux? I can't imagine anyone trying to do that > >> in eBPF, although I'm willing to be surprised. Being able to > >> enforce a policy isn't the only criteria for an LSM. > > what are the other criteria? > > They include, but are not limited to, performance impact > and the ability to be analyzed. Right and BPF is the only thing that exists in the kernel where the verifier knows precisely the number of instructions the critical path through the program will take. Currently we don't quantify this cost for bpf helpers, but it's easy to add. Can you do this for smack? Can you tell upfront the longest execution time for all security rules? > It has to be fast, or the networking people are > going to have fits. You can't require the addition > of a pointer into the skb because it'll get rejected > out of hand. You can't completely refactor the vfs locking > to accommodate you needs. I'm not sure why you got such impression. I'm not proposing to refactor vfs or add fields to skb. Once we have equivalent to smack policy implemented in bpf-based lsm let's do performance benchmarking and compare actual numbers instead of hypothesizing about them. Which policy do you think would be the most representative of smack use case? > > > > >> I see many issues with a BPF <-> vfs interface. > > There is no such interface today. What do you have in mind? > > You can't implement SELinux or Smack using BPF without a way > to manipulate inode data. Are you talking about inode->i_security ? That's not manipulating inode data. It's attaching extra metadata to inode object without changing inode itself. BPF can do it already via hash maps. It's not as fast as direct pointer access, but for many use cases it's good enough. If it turns out to be a performance limiting factor we will accelerate it. > >> the mechanisms needed for the concerns of the day. Ideally, > >> we should be able to drop mechanisms when we decide that they > >> no longer add value. > > Exactly. bpf-based lsm must not add to kernel abi. > > Huh? I have no idea where that came from. It sounds to me that some folks in the community got wrong impression that anything that BPF accesses is magically turning that thing into stable kernel ABI. That is not true. BPF progs had access _all_ kernel data pointers and structures for years without turning the whole kernel into stable ABI. I want to make sure that this part is understood. This is also a requirement for bpf-based LSM. It must not make LSM hooks into stable ABI.
On 05/11/2019 20:34, Alexei Starovoitov wrote: > On Tue, Nov 05, 2019 at 07:01:41PM +0100, Mickaël Salaün wrote: >> >> On 05/11/2019 18:18, Alexei Starovoitov wrote: >>> On Mon, Nov 04, 2019 at 06:21:43PM +0100, Mickaël Salaün wrote: >>>> Add a first Landlock hook that can be used to enforce a security policy >>>> or to audit some process activities. For a sandboxing use-case, it is >>>> needed to inform the kernel if a task can legitimately debug another. >>>> ptrace(2) can also be used by an attacker to impersonate another task >>>> and remain undetected while performing malicious activities. >>>> >>>> Using ptrace(2) and related features on a target process can lead to a >>>> privilege escalation. A sandboxed task must then be able to tell the >>>> kernel if another task is more privileged, via ptrace_may_access(). >>>> >>>> Signed-off-by: Mickaël Salaün <mic@digikod.net> >>> ... >>>> +static int check_ptrace(struct landlock_domain *domain, >>>> + struct task_struct *tracer, struct task_struct *tracee) >>>> +{ >>>> + struct landlock_hook_ctx_ptrace ctx_ptrace = { >>>> + .prog_ctx = { >>>> + .tracer = (uintptr_t)tracer, >>>> + .tracee = (uintptr_t)tracee, >>>> + }, >>>> + }; >>> >>> So you're passing two kernel pointers obfuscated as u64 into bpf program >>> yet claiming that the end goal is to make landlock unprivileged?! >>> The most basic security hole in the tool that is aiming to provide security. >> >> How could you used these pointers without dedicated BPF helpers? This >> context items are typed as PTR_TO_TASK and can't be used without a >> dedicated helper able to deal with ARG_PTR_TO_TASK. Moreover, pointer >> arithmetic is explicitly forbidden (and I added tests for that). Did I >> miss something? > > It's a pointer leak. The lifetimes of the pointers are scoped by the two LSM hooks that expose them. The LSM framework guarantee that they are safe to use in this context. > >> >>> >>> I think the only way bpf-based LSM can land is both landlock and KRSI >>> developers work together on a design that solves all use cases. >> >> As I said in a previous cover letter [1], that would be great. I think >> that the current Landlock bases (almost everything from this series >> except the seccomp interface) should meet both needs, but I would like >> to have the point of view of the KRSI developers. >> >> [1] https://lore.kernel.org/lkml/20191029171505.6650-1-mic@digikod.net/ >> >>> BPF is capable >>> to be a superset of all existing LSMs whereas landlock and KRSI propsals today >>> are custom solutions to specific security concerns. BPF subsystem was extended >>> with custom things in the past. In networking we have lwt, skb, tc, xdp, sk >>> program types with a lot of overlapping functionality. We couldn't figure out >>> how to generalize them into single 'networking' program. Now we can and we >>> should. Accepting two partially overlapping bpf-based LSMs would be repeating >>> the same mistake again. >> >> I'll let the LSM maintainers comment on whether BPF could be a superset >> of all LSM, but given the complexity of an access-control system, I have >> some doubts though. Anyway, we need to start somewhere and then iterate. >> This patch series is a first step. > > I would like KRSI folks to speak up. So far I don't see any sharing happening > between landlock and KRSI. You're claiming this set is a first step. They're > claiming the same about their patches. I'd like to set a patchset that was > jointly developed. With all due respect, Landlock got much more feedback than KRSI and I think this thirteenth Landlock patch series is more mature than the first KRSI RFC. I'm open to concrete suggestions and I'm willing to collaborate with the KRSI folks if they want to. However, I'm OK if they don't want to use Landlock as a common ground, and I don't think it should be a blocker for any of the projects. Perfect is the enemy of good. ;)
On 11/5/2019 1:54 PM, Alexei Starovoitov wrote: > On Tue, Nov 05, 2019 at 11:55:17AM -0800, Casey Schaufler wrote: >> On 11/5/2019 11:31 AM, Alexei Starovoitov wrote: >>> On Tue, Nov 05, 2019 at 09:55:42AM -0800, Casey Schaufler wrote: >>>> On 11/5/2019 9:18 AM, Alexei Starovoitov wrote: >>>>> On Mon, Nov 04, 2019 at 06:21:43PM +0100, Mickaël Salaün wrote: >>>>>> Add a first Landlock hook that can be used to enforce a security policy >>>>>> or to audit some process activities. For a sandboxing use-case, it is >>>>>> needed to inform the kernel if a task can legitimately debug another. >>>>>> ptrace(2) can also be used by an attacker to impersonate another task >>>>>> and remain undetected while performing malicious activities. >>>>>> >>>>>> Using ptrace(2) and related features on a target process can lead to a >>>>>> privilege escalation. A sandboxed task must then be able to tell the >>>>>> kernel if another task is more privileged, via ptrace_may_access(). >>>>>> >>>>>> Signed-off-by: Mickaël Salaün <mic@digikod.net> >>>>> ... >>>>>> +static int check_ptrace(struct landlock_domain *domain, >>>>>> + struct task_struct *tracer, struct task_struct *tracee) >>>>>> +{ >>>>>> + struct landlock_hook_ctx_ptrace ctx_ptrace = { >>>>>> + .prog_ctx = { >>>>>> + .tracer = (uintptr_t)tracer, >>>>>> + .tracee = (uintptr_t)tracee, >>>>>> + }, >>>>>> + }; >>>>> So you're passing two kernel pointers obfuscated as u64 into bpf program >>>>> yet claiming that the end goal is to make landlock unprivileged?! >>>>> The most basic security hole in the tool that is aiming to provide security. >>>>> >>>>> I think the only way bpf-based LSM can land is both landlock and KRSI >>>>> developers work together on a design that solves all use cases. BPF is capable >>>>> to be a superset of all existing LSMs >>>> I can't agree with this. Nope. There are many security models >>>> for which BPF introduces excessive complexity. You don't need >>>> or want the generality of a general purpose programming language >>>> to implement Smack or TOMOYO. Or a simple Bell & LaPadula for >>>> that matter. SELinux? I can't imagine anyone trying to do that >>>> in eBPF, although I'm willing to be surprised. Being able to >>>> enforce a policy isn't the only criteria for an LSM. >>> what are the other criteria? >> They include, but are not limited to, performance impact >> and the ability to be analyzed. > Right and BPF is the only thing that exists in the kernel where the verifier > knows precisely the number of instructions the critical path through the > program will take. Currently we don't quantify this cost for bpf helpers, but > it's easy to add. Can you do this for smack? Can you tell upfront the longest > execution time for all security rules? There's much more to analyze than number of instructions. There's also completion of policy enforcement. There are lots of tools for measuring performance within the kernel. >> It has to be fast, or the networking people are >> going to have fits. You can't require the addition >> of a pointer into the skb because it'll get rejected >> out of hand. You can't completely refactor the vfs locking >> to accommodate you needs. > I'm not sure why you got such impression. I'm not proposing to refactor vfs or > add fields to skb. I'm not saying you did. Those are examples of things you would have trouble with. > Once we have equivalent to smack policy implemented in > bpf-based lsm let's do performance benchmarking and compare actual numbers > instead of hypothesizing about them. Which policy do you think would be > the most representative of smack use case? The Tizen3 Three domain model will do just fine. https://wiki.tizen.org/Security:SmackThreeDomainModel > >>>> I see many issues with a BPF <-> vfs interface. >>> There is no such interface today. What do you have in mind? >> You can't implement SELinux or Smack using BPF without a way >> to manipulate inode data. > Are you talking about inode->i_security ? That's not manipulating inode data. Poppycock. > It's attaching extra metadata to inode object without changing inode itself. Where I come from, we call that inode object data. > BPF can do it already via hash maps. It's not as fast as direct pointer access, Then you're not listening. Performance MATTERS! > but for many use cases it's good enough. If it turns out to be a performance > limiting factor we will accelerate it. How many times have I heard that bit of rubbish? No. You can't start with a bad design and tweak it to acceptability later. >>>> the mechanisms needed for the concerns of the day. Ideally, >>>> we should be able to drop mechanisms when we decide that they >>>> no longer add value. >>> Exactly. bpf-based lsm must not add to kernel abi. >> Huh? I have no idea where that came from. > It sounds to me that some folks in the community got wrong impression that > anything that BPF accesses is magically turning that thing into stable kernel > ABI. That is not true. BPF progs had access _all_ kernel data pointers and > structures for years without turning the whole kernel into stable ABI. I want > to make sure that this part is understood. This is also a requirement for > bpf-based LSM. It must not make LSM hooks into stable ABI. >
On 05-Nov 11:34, Alexei Starovoitov wrote: > On Tue, Nov 05, 2019 at 07:01:41PM +0100, Mickaël Salaün wrote: > > > > On 05/11/2019 18:18, Alexei Starovoitov wrote: > > > On Mon, Nov 04, 2019 at 06:21:43PM +0100, Mickaël Salaün wrote: > > >> Add a first Landlock hook that can be used to enforce a security policy > > >> or to audit some process activities. For a sandboxing use-case, it is > > >> needed to inform the kernel if a task can legitimately debug another. > > >> ptrace(2) can also be used by an attacker to impersonate another task > > >> and remain undetected while performing malicious activities. > > >> > > >> Using ptrace(2) and related features on a target process can lead to a > > >> privilege escalation. A sandboxed task must then be able to tell the > > >> kernel if another task is more privileged, via ptrace_may_access(). > > >> > > >> Signed-off-by: Mickaël Salaün <mic@digikod.net> > > > ... > > >> +static int check_ptrace(struct landlock_domain *domain, > > >> + struct task_struct *tracer, struct task_struct *tracee) > > >> +{ > > >> + struct landlock_hook_ctx_ptrace ctx_ptrace = { > > >> + .prog_ctx = { > > >> + .tracer = (uintptr_t)tracer, > > >> + .tracee = (uintptr_t)tracee, > > >> + }, > > >> + }; > > > > > > So you're passing two kernel pointers obfuscated as u64 into bpf program > > > yet claiming that the end goal is to make landlock unprivileged?! > > > The most basic security hole in the tool that is aiming to provide security. > > > > How could you used these pointers without dedicated BPF helpers? This > > context items are typed as PTR_TO_TASK and can't be used without a > > dedicated helper able to deal with ARG_PTR_TO_TASK. Moreover, pointer > > arithmetic is explicitly forbidden (and I added tests for that). Did I > > miss something? > > It's a pointer leak. > > > > > > > > > I think the only way bpf-based LSM can land is both landlock and KRSI > > > developers work together on a design that solves all use cases. > > > > As I said in a previous cover letter [1], that would be great. I think > > that the current Landlock bases (almost everything from this series > > except the seccomp interface) should meet both needs, but I would like > > to have the point of view of the KRSI developers. > > > > [1] https://lore.kernel.org/lkml/20191029171505.6650-1-mic@digikod.net/ > > > > > BPF is capable > > > to be a superset of all existing LSMs whereas landlock and KRSI propsals today > > > are custom solutions to specific security concerns. BPF subsystem was extended > > > with custom things in the past. In networking we have lwt, skb, tc, xdp, sk > > > program types with a lot of overlapping functionality. We couldn't figure out > > > how to generalize them into single 'networking' program. Now we can and we > > > should. Accepting two partially overlapping bpf-based LSMs would be repeating > > > the same mistake again. > > > > I'll let the LSM maintainers comment on whether BPF could be a superset > > of all LSM, but given the complexity of an access-control system, I have > > some doubts though. Anyway, we need to start somewhere and then iterate. > > This patch series is a first step. > > I would like KRSI folks to speak up. So far I don't see any sharing happening > between landlock and KRSI. You're claiming this set is a first step. They're > claiming the same about their patches. I'd like to set a patchset that was > jointly developed. We are willing to collaborate with the Landlock developers and come up with a common approach that would work for Landlock and KRSI. I want to mention that this collaboration and the current Landlock approach of using an eBPF based LSM for unprivileged sandboxing only makes sense if unprivileged usage of eBPF is going to be ever allowed. Purely from a technical standpoint, both the current designs for Landlock and KRSI target separate use cases and it would not be possible to build "one on top of the other". We've tried to identify the lowest denominator ("eBPF+LSM") requirements for both Landlock (unprivileged sandboxing / Discretionary Access Control) and KRSI (flexibility and unification of privileged MAC and Audit) and prototyped an implementation based on the newly added / upcoming features in BPF. We've been successfully able to prototype the use cases for KRSI (privileged MAC and Audit) using this "eBPF+LSM" and shared our approach at the Linux Security Summit [1]: * Use the new in-kernel BTF (CO-RE eBPF programs) [2] and the ability of the BPF verifier to use the BTF information for access validation to provide a more generic way to attach to the various LSM hooks. This potentially saves a lot of redundant work: - Creation of new program types. - Multiple types of contexts (or a single context with Unions). - Changes to the verifier and creation of new BPF argument types (eg. PTR_TO_TASK) * These new BPF features also alleviate the original concerns that we raised when initially proposing KRSI and designing for precise BPF helpers. We have some patches coming up which incorporate these new changes and will be sharing something on the mailing list after some cleanup. We can use the common "eBPF+LSM" for both privileged MAC and Audit and unprivileged sandboxing i.e. Discretionary Access Control. Here's what it could look like: * Common infrastructure allows attachment to all hooks which works well for privileged MAC and Audit. This could be extended to provide another attachment type for unprivileged DAC, which can restrict the hooks that can be attached to, and also the information that is exposed to the eBPF programs which is something that Landlock could build. * This attachment could use the proposed landlock domains and attach to the task_struct providing the discretionary access control semantics. [1] https://static.sched.com/hosted_files/lsseu2019/a2/Kernel%20Runtime%20Security%20Instrumentation.pdf [2] http://vger.kernel.org/bpfconf2019_talks/bpf-core.pdf - KP Singh >
On 05-Nov 19:01, Mickaël Salaün wrote: > > On 05/11/2019 18:18, Alexei Starovoitov wrote: > > On Mon, Nov 04, 2019 at 06:21:43PM +0100, Mickaël Salaün wrote: > >> Add a first Landlock hook that can be used to enforce a security policy > >> or to audit some process activities. For a sandboxing use-case, it is > >> needed to inform the kernel if a task can legitimately debug another. > >> ptrace(2) can also be used by an attacker to impersonate another task > >> and remain undetected while performing malicious activities. > >> > >> Using ptrace(2) and related features on a target process can lead to a > >> privilege escalation. A sandboxed task must then be able to tell the > >> kernel if another task is more privileged, via ptrace_may_access(). > >> > >> Signed-off-by: Mickaël Salaün <mic@digikod.net> > > ... > >> +static int check_ptrace(struct landlock_domain *domain, > >> + struct task_struct *tracer, struct task_struct *tracee) > >> +{ > >> + struct landlock_hook_ctx_ptrace ctx_ptrace = { > >> + .prog_ctx = { > >> + .tracer = (uintptr_t)tracer, > >> + .tracee = (uintptr_t)tracee, > >> + }, > >> + }; > > > > So you're passing two kernel pointers obfuscated as u64 into bpf program > > yet claiming that the end goal is to make landlock unprivileged?! > > The most basic security hole in the tool that is aiming to provide security. > > How could you used these pointers without dedicated BPF helpers? This > context items are typed as PTR_TO_TASK and can't be used without a > dedicated helper able to deal with ARG_PTR_TO_TASK. Moreover, pointer > arithmetic is explicitly forbidden (and I added tests for that). Did I > miss something? > > > > > I think the only way bpf-based LSM can land is both landlock and KRSI > > developers work together on a design that solves all use cases. > > As I said in a previous cover letter [1], that would be great. I think > that the current Landlock bases (almost everything from this series > except the seccomp interface) should meet both needs, but I would like > to have the point of view of the KRSI developers. As I mentioned we are willing to collaborate but the current landlock patches does not meet the needs for KRSI: * One program type per use-case (eg. LANDLOCK_PROG_PTRACE) as opposed to a single program type. This is something that KRSI proposed in it's initial design [1] and the new common "eBPF + LSM" based approach [2] would maintain as well. * Landlock chooses to have multiple LSM hooks per landlock hook which is more restrictive. It's not easy to write precise MAC and Audit policies for a privileged LSM based on this and this ends up bloating the context that needs to be maintained and requires avoidable boilerplate work in the kernel. [1] https://lore.kernel.org/patchwork/project/lkml/list/?series=410101 [2] https://lore.kernel.org/bpf/20191106100655.GA18815@chromium.org/T/#u - KP Singh > > [1] https://lore.kernel.org/lkml/20191029171505.6650-1-mic@digikod.net/ > > > BPF is capable > > to be a superset of all existing LSMs whereas landlock and KRSI propsals today > > are custom solutions to specific security concerns. BPF subsystem was extended > > with custom things in the past. In networking we have lwt, skb, tc, xdp, sk > > program types with a lot of overlapping functionality. We couldn't figure out > > how to generalize them into single 'networking' program. Now we can and we > > should. Accepting two partially overlapping bpf-based LSMs would be repeating > > the same mistake again. > > I'll let the LSM maintainers comment on whether BPF could be a superset > of all LSM, but given the complexity of an access-control system, I have > some doubts though. Anyway, we need to start somewhere and then iterate. > This patch series is a first step.
On 06/11/2019 11:06, KP Singh wrote: > On 05-Nov 11:34, Alexei Starovoitov wrote: >> On Tue, Nov 05, 2019 at 07:01:41PM +0100, Mickaël Salaün wrote: >>> On 05/11/2019 18:18, Alexei Starovoitov wrote: [...] >>>> I think the only way bpf-based LSM can land is both landlock and KRSI >>>> developers work together on a design that solves all use cases. >>> >>> As I said in a previous cover letter [1], that would be great. I think >>> that the current Landlock bases (almost everything from this series >>> except the seccomp interface) should meet both needs, but I would like >>> to have the point of view of the KRSI developers. >>> >>> [1] https://lore.kernel.org/lkml/20191029171505.6650-1-mic@digikod.net/ >>> >>>> BPF is capable >>>> to be a superset of all existing LSMs whereas landlock and KRSI propsals today >>>> are custom solutions to specific security concerns. BPF subsystem was extended >>>> with custom things in the past. In networking we have lwt, skb, tc, xdp, sk >>>> program types with a lot of overlapping functionality. We couldn't figure out >>>> how to generalize them into single 'networking' program. Now we can and we >>>> should. Accepting two partially overlapping bpf-based LSMs would be repeating >>>> the same mistake again. >>> >>> I'll let the LSM maintainers comment on whether BPF could be a superset >>> of all LSM, but given the complexity of an access-control system, I have >>> some doubts though. Anyway, we need to start somewhere and then iterate. >>> This patch series is a first step. >> >> I would like KRSI folks to speak up. So far I don't see any sharing happening >> between landlock and KRSI. You're claiming this set is a first step. They're >> claiming the same about their patches. I'd like to set a patchset that was >> jointly developed. > > We are willing to collaborate with the Landlock developers and come up > with a common approach that would work for Landlock and KRSI. I want > to mention that this collaboration and the current Landlock approach > of using an eBPF based LSM for unprivileged sandboxing only makes sense > if unprivileged usage of eBPF is going to be ever allowed. The ability to *potentially* do unprivileged sandboxing is definitely not tied nor a blocker to the unprivileged usage of eBPF. As explained in the documentation [1] (cf. Guiding principles / Unprivileged use), Landlock is designed to be as safe as possible (from a security point of view). The impact is more complex and important than just using unprivileged eBPF, which may not be required. Unprivileged use of eBPF would be nice, but I think the current direction is to extend the Linux capabilities with one or multiple dedicated to eBPF [2] (e.g. CAP_BPF + something else), which may be even better (and a huge difference with CAP_SYS_ADMIN, a.k.a. privileged mode or root). Landlock is designed to deal with unprivileged (i.e. non-root) use cases, but of course, if the Landlock architecture may enable to do unprivileged stuff, it definitely can do privileged stuff too. However, having an architecture designed with safe unprivileged use in mind can't be achieve afterwards. [1] https://lore.kernel.org/lkml/20191104172146.30797-8-mic@digikod.net/ [2] https://lore.kernel.org/bpf/20190827205213.456318-1-ast@kernel.org/ > > Purely from a technical standpoint, both the current designs for > Landlock and KRSI target separate use cases and it would not be > possible to build "one on top of the other". We've tried to identify > the lowest denominator ("eBPF+LSM") requirements for both Landlock > (unprivileged sandboxing / Discretionary Access Control) and KRSI > (flexibility and unification of privileged MAC and Audit) and > prototyped an implementation based on the newly added / upcoming > features in BPF. This is not as binary as that. Sandboxing can be seen as DAC but also as MAC, depending on the subject which apply the security policy and the subjects which are enforced by this policy. If the sandboxing is applied system-wide, it is what we usually call MAC. DAC, in the Linux world, enables any user to restrict access to their files to other users. With Landlock it is not the same because a process can restrict itself but also enforce these restrictions on all its future children (which may be malicious, whatever their UID/GID). The threat and the definition of the attacker are not the same in both cases. With the Linux DAC the potentially malicious subjects are the other users, whereas with Landlock the potentially malicious subjects are (for now) the current process and all its children. Another way to explain it, and how Landlock is designed, is that a specific enforcement (i.e. a set of BPF programs) is tied to a domain, in which a set of subject are. From this perspective, this approach (subjects/tasks in a domain) is orthogonal to the DAC system (subjects/users). This design may apply to a system-wide MAC system by putting all the system tasks in one domain, and managing restrictions (by subject) with other means (e.g. task's UID, command-line strings, environment variables). In short, Landlock (in this patch series) is closer to a (potentially scoped) MAC system. But thanks to eBPF, Landlock is firstly a programmatic access-control, which means that the one who write the programs and tie them to a set of tasks, can implement their own access-control system (e.g. RBAC, time-based…), or something else (e.g. an audit system). The audit part can simply be achieve with dedicated helpers and programs that always allow accesses. Landlock evolved over multiple iterations and is now designed to be very flexible. The current way to enforce a security policy is to go through the seccomp syscall (which makes sense for multiple reasons explained and accepted before). But Landlock is designed to enable similar enforcements (or audit) with other ways to define a domain (e.g. cgroups [3], or system-wide securityfs as done in KRSI). Indeed, the only part tied to this scoped enforcement is in the domain_syscall.c file. A new file domain_fs.c could be added to implement a securityfs for a system-wide enforcement (and have other features as KRSI does). [3] https://lore.kernel.org/lkml/20160914072415.26021-17-mic@digikod.net/ One possible important difference between Landlock and KRSI right now is the BPF program management. Both manage a list of programs per hook. However KRSI needs to be able to replace a program in these lists. This is not implemented in this Landlock patch series, first because it is not the main use-case and it is safer to have an append-only way to add restrictions (cf. seccomp-bpf model), and second because it is simpler to deal with immutable lists. However, it is worth considering extending the Landlock domain management with the ability to update the program lists. One challenge may be to identify which program should be replaced (which KRSI does with the program name). I think it would be wiser to implement this in a second step though, maybe not for the syscall interface (thanks to a new seccomp operation), but first with the securityfs one. > > We've been successfully able to prototype the use cases for KRSI > (privileged MAC and Audit) using this "eBPF+LSM" and shared our > approach at the Linux Security Summit [1]: > > * Use the new in-kernel BTF (CO-RE eBPF programs) [2] and the ability > of the BPF verifier to use the BTF information for access validation > to provide a more generic way to attach to the various LSM hooks. > This potentially saves a lot of redundant work: > > - Creation of new program types. > - Multiple types of contexts (or a single context with Unions). > - Changes to the verifier and creation of new BPF argument types > (eg. PTR_TO_TASK) As I understood from the LSS talk, KRSI's approach is to use the same hooks as LSM (cf. the securityfs). As said Alexei [4] "It must not make LSM hooks into stable ABI". Moveover, the LSM hooks may change according to internal kernel evolution, and their semantic may not make sense from a user space point of view. This is one reason for which Lanlock abstract those hooks into something that is simpler and designed to fit well with eBPF (program contexts and their attached types, as explained in the documentation). [4] https://lore.kernel.org/lkml/20191105215453.szhdkrvuekwfz6le@ast-mbp.dhcp.thefacebook.com/ How does KRSI plan to deal with one LSM hook being split in two hooks in a next version of the kernel (cf. [5])? [5] https://lore.kernel.org/lkml/20190910115527.5235-6-kpsingh@chromium.org/ Another reason to have multiple different attach types/contexts (cf. landlock_domain->programs[]) is to limit useless BPF program interpretation (in addition to the non-system-wide scoped of programs). It also enables to handle and verify strict context use (which is also explain in the Guiding principles). It would be a huge wast of time to run every BPF programs for all LSM hooks. KRSI does the same but instead of relying on the program type it rely on the list tied to the securityfs file. BTF is great, but as far as I know, it's goal is to easily deal with the moving kernel ABI (e.g. task_struct layout, config/constant variables), and it is definitely useful to programs using bpf_probe_read() and similar accessors. However, I don't see how KRSI would avoid BPF types thanks to BTF. There is only one program type for Landlock (i.e. BPF_PROG_TYPE_LANDLOCK_HOOK), and I don't see why adding new program *attach* types (e.g. BPF_LANDLOCK_PTRACE) may be an issue. The kernel will still need to be modified to implement new hooks and the new BPF helpers anyway, BTF will not change that, except maybe if the internal LSM API is exposed in a way or another to BPF (thanks to BTF), which does not seem acceptable. Am I missing something? The current KRSI approach is to allow a common set of helpers to be called by all programs (because there is no way to differentiate them with their type). How KRSI would deal with kernel objects other than the current task (e.g. a ptrace hook with a tracer and a tracee, a file open/read) with the struct krsi_ctx unions [6]? [6] https://lore.kernel.org/lkml/20190910115527.5235-7-kpsingh@chromium.org/ How does KRSI plan to deal with security blobs? > > * These new BPF features also alleviate the original concerns that we > raised when initially proposing KRSI and designing for precise BPF > helpers. We have some patches coming up which incorporate these new > changes and will be sharing something on the mailing list after some > cleanup. > > We can use the common "eBPF+LSM" for both privileged MAC and Audit and > unprivileged sandboxing i.e. Discretionary Access Control. > Here's what it could look like: > > * Common infrastructure allows attachment to all hooks which works well > for privileged MAC and Audit. This could be extended to provide > another attachment type for unprivileged DAC, which can restrict the > hooks that can be attached to, and also the information that is > exposed to the eBPF programs which is something that Landlock could > build. I agree that the "privileged-only" hooks should be a superset of the "security-safe-and-potentially-unprivileged" hooks. :) However, as said previously, I'm convinced it is a requirement to have abstract hooks (and associated program attach types) as defined by Landlock. I'm not sure what you mean by "the information that is exposed to the eBPF program". Is it the current Landlock implementation of specific contexts and attach types? > > * This attachment could use the proposed landlock domains and attach to > the task_struct providing the discretionary access control semantics. Not task_struct but creds, yes. This is a characteristic of sandboxing, which may not be useful for the KRSI use case. It makes sense for KRSI to attach program sets (or Landlock domains) to the whole system, then using the creds does not make sense here. This difference is small and a previous version of Landlock already validated this use case with cgroups [3] (which is postponed to simplify the patch series). [3] https://lore.kernel.org/lkml/20160914072415.26021-17-mic@digikod.net/ > > [1] https://static.sched.com/hosted_files/lsseu2019/a2/Kernel%20Runtime%20Security%20Instrumentation.pdf > [2] http://vger.kernel.org/bpfconf2019_talks/bpf-core.pdf > > - KP Singh I think it should be OK to first land something close to this Landlock patch series and then we could extend the domain management features and add the securityfs support that KRSI needs. The main concern seems to be about hook definitions. Another approach would be to land Landlock and KRSI as distinct LSM while trying as much as possible to mutualize code/helpers.
On 06/11/2019 11:15, KP Singh wrote: > On 05-Nov 19:01, Mickaël Salaün wrote: >> On 05/11/2019 18:18, Alexei Starovoitov wrote: [...] >>> >>> I think the only way bpf-based LSM can land is both landlock and KRSI >>> developers work together on a design that solves all use cases. >> >> As I said in a previous cover letter [1], that would be great. I think >> that the current Landlock bases (almost everything from this series >> except the seccomp interface) should meet both needs, but I would like >> to have the point of view of the KRSI developers. > > As I mentioned we are willing to collaborate but the current landlock > patches does not meet the needs for KRSI: > > * One program type per use-case (eg. LANDLOCK_PROG_PTRACE) as opposed to > a single program type. This is something that KRSI proposed in it's > initial design [1] and the new common "eBPF + LSM" based approach > [2] would maintain as well. As ask in my previous email [1], I don't see how KRSI would efficiently deal with other LSM hooks with a unique program (attach) type. [1] https://lore.kernel.org/lkml/813cedde-8ed7-2d3b-883d-909efa978d41@digikod.net/ > > * Landlock chooses to have multiple LSM hooks per landlock hook which is > more restrictive. It's not easy to write precise MAC and Audit > policies for a privileged LSM based on this and this ends up bloating > the context that needs to be maintained and requires avoidable > boilerplate work in the kernel. Why do you think it is more restrictive or it adds boilerplate work? How does KRSI will deal with more complex hooks than execve-like with multiple kernel objects? > > [1] https://lore.kernel.org/patchwork/project/lkml/list/?series=410101 > [2] https://lore.kernel.org/bpf/20191106100655.GA18815@chromium.org/T/#u > > - KP Singh
On 06-Nov 17:55, Mickaël Salaün wrote: > > On 06/11/2019 11:06, KP Singh wrote: > > On 05-Nov 11:34, Alexei Starovoitov wrote: > >> On Tue, Nov 05, 2019 at 07:01:41PM +0100, Mickaël Salaün wrote: > >>> On 05/11/2019 18:18, Alexei Starovoitov wrote: > > [...] > > >>>> I think the only way bpf-based LSM can land is both landlock and KRSI > >>>> developers work together on a design that solves all use cases. > >>> > >>> As I said in a previous cover letter [1], that would be great. I think > >>> that the current Landlock bases (almost everything from this series > >>> except the seccomp interface) should meet both needs, but I would like > >>> to have the point of view of the KRSI developers. > >>> > >>> [1] https://lore.kernel.org/lkml/20191029171505.6650-1-mic@digikod.net/ > >>> > >>>> BPF is capable > >>>> to be a superset of all existing LSMs whereas landlock and KRSI propsals today > >>>> are custom solutions to specific security concerns. BPF subsystem was extended > >>>> with custom things in the past. In networking we have lwt, skb, tc, xdp, sk > >>>> program types with a lot of overlapping functionality. We couldn't figure out > >>>> how to generalize them into single 'networking' program. Now we can and we > >>>> should. Accepting two partially overlapping bpf-based LSMs would be repeating > >>>> the same mistake again. > >>> > >>> I'll let the LSM maintainers comment on whether BPF could be a superset > >>> of all LSM, but given the complexity of an access-control system, I have > >>> some doubts though. Anyway, we need to start somewhere and then iterate. > >>> This patch series is a first step. > >> > >> I would like KRSI folks to speak up. So far I don't see any sharing happening > >> between landlock and KRSI. You're claiming this set is a first step. They're > >> claiming the same about their patches. I'd like to set a patchset that was > >> jointly developed. > > > > We are willing to collaborate with the Landlock developers and come up > > with a common approach that would work for Landlock and KRSI. I want > > to mention that this collaboration and the current Landlock approach > > of using an eBPF based LSM for unprivileged sandboxing only makes sense > > if unprivileged usage of eBPF is going to be ever allowed. > > The ability to *potentially* do unprivileged sandboxing is definitely > not tied nor a blocker to the unprivileged usage of eBPF. As explained > in the documentation [1] (cf. Guiding principles / Unprivileged use), > Landlock is designed to be as safe as possible (from a security point of > view). The impact is more complex and important than just using > unprivileged eBPF, which may not be required. Unprivileged use of eBPF > would be nice, but I think the current direction is to extend the Linux > capabilities with one or multiple dedicated to eBPF [2] (e.g. CAP_BPF + > something else), which may be even better (and a huge difference with > CAP_SYS_ADMIN, a.k.a. privileged mode or root). Landlock is designed to > deal with unprivileged (i.e. non-root) use cases, but of course, if the > Landlock architecture may enable to do unprivileged stuff, it definitely > can do privileged stuff too. However, having an architecture designed > with safe unprivileged use in mind can't be achieve afterwards. > > [1] https://lore.kernel.org/lkml/20191104172146.30797-8-mic@digikod.net/ > [2] https://lore.kernel.org/bpf/20190827205213.456318-1-ast@kernel.org/ > > > > > > Purely from a technical standpoint, both the current designs for > > Landlock and KRSI target separate use cases and it would not be > > possible to build "one on top of the other". We've tried to identify > > the lowest denominator ("eBPF+LSM") requirements for both Landlock > > (unprivileged sandboxing / Discretionary Access Control) and KRSI > > (flexibility and unification of privileged MAC and Audit) and > > prototyped an implementation based on the newly added / upcoming > > features in BPF. > > This is not as binary as that. Sandboxing can be seen as DAC but also as > MAC, depending on the subject which apply the security policy and the > subjects which are enforced by this policy. If the sandboxing is applied > system-wide, it is what we usually call MAC. DAC, in the Linux world, > enables any user to restrict access to their files to other users. > > With Landlock it is not the same because a process can restrict itself > but also enforce these restrictions on all its future children (which > may be malicious, whatever their UID/GID). The threat and the definition > of the attacker are not the same in both cases. With the Linux DAC the > potentially malicious subjects are the other users, whereas with > Landlock the potentially malicious subjects are (for now) the current > process and all its children. Another way to explain it, and how > Landlock is designed, is that a specific enforcement (i.e. a set of BPF > programs) is tied to a domain, in which a set of subject are. From this > perspective, this approach (subjects/tasks in a domain) is orthogonal to > the DAC system (subjects/users). This design may apply to a system-wide > MAC system by putting all the system tasks in one domain, and managing > restrictions (by subject) with other means (e.g. task's UID, > command-line strings, environment variables). In short, Landlock (in > this patch series) is closer to a (potentially scoped) MAC system. But > thanks to eBPF, Landlock is firstly a programmatic access-control, which > means that the one who write the programs and tie them to a set of > tasks, can implement their own access-control system (e.g. RBAC, > time-based…), or something else (e.g. an audit system). > > The audit part can simply be achieve with dedicated helpers and programs > that always allow accesses. > > Landlock evolved over multiple iterations and is now designed to be very > flexible. The current way to enforce a security policy is to go through > the seccomp syscall (which makes sense for multiple reasons explained > and accepted before). But Landlock is designed to enable similar > enforcements (or audit) with other ways to define a domain (e.g. cgroups > [3], or system-wide securityfs as done in KRSI). Indeed, the only part > tied to this scoped enforcement is in the domain_syscall.c file. A new > file domain_fs.c could be added to implement a securityfs for a > system-wide enforcement (and have other features as KRSI does). > Given the current way landlock exposes LSM hooks, I don't think it's possible to build system-wide detections. But let’s try to come to a consensus on the semantics of the how the LSM hooks are exposed to BPF. At the moment I think we should: * Bring the core interface exposed to eBPF closer to the LSM surface in a way that supports both use cases. One way Landlock can still provide a more abstract interface is by providing some BPF helper libraries that build on top of the core framework. * Use a single BPF program type; this is necessary for a key requirement of KRSI, i.e. runtime instrumentation. The upcoming prototype should illustrate how this works for KRSI - note that it’s possible to vary the context types exposed by different hooks. It would be nice to get the BPF maintainers’ opinion on these points. > [3] https://lore.kernel.org/lkml/20160914072415.26021-17-mic@digikod.net/ > > One possible important difference between Landlock and KRSI right now is > the BPF program management. Both manage a list of programs per hook. > However KRSI needs to be able to replace a program in these lists. This > is not implemented in this Landlock patch series, first because it is > not the main use-case and it is safer to have an append-only way to add > restrictions (cf. seccomp-bpf model), and second because it is simpler > to deal with immutable lists. However, it is worth considering extending > the Landlock domain management with the ability to update the program > lists. One challenge may be to identify which program should be replaced > (which KRSI does with the program name). I think it would be wiser to > implement this in a second step though, maybe not for the syscall > interface (thanks to a new seccomp operation), but first with the > securityfs one. > > > > > > We've been successfully able to prototype the use cases for KRSI > > (privileged MAC and Audit) using this "eBPF+LSM" and shared our > > approach at the Linux Security Summit [1]: > > > > * Use the new in-kernel BTF (CO-RE eBPF programs) [2] and the ability > > of the BPF verifier to use the BTF information for access validation > > to provide a more generic way to attach to the various LSM hooks. > > This potentially saves a lot of redundant work: > > > > - Creation of new program types. > > - Multiple types of contexts (or a single context with Unions). > > - Changes to the verifier and creation of new BPF argument types > > (eg. PTR_TO_TASK) > > As I understood from the LSS talk, KRSI's approach is to use the same > hooks as LSM (cf. the securityfs). As said Alexei [4] "It must not make > LSM hooks into stable ABI". Moveover, the LSM hooks may change > according to internal kernel evolution, and their semantic may not make I think you misunderstand Alexei here. I will let him elaborate. > sense from a user space point of view. This is one reason for which > Lanlock abstract those hooks into something that is simpler and designed > to fit well with eBPF (program contexts and their attached types, as > explained in the documentation). > > [4] > https://lore.kernel.org/lkml/20191105215453.szhdkrvuekwfz6le@ast-mbp.dhcp.thefacebook.com/ > > How does KRSI plan to deal with one LSM hook being split in two hooks in > a next version of the kernel (cf. [5])? How often has that happened in the past? And even if it does happen, it can still be handled as a part of the base framework we are trying to implement. > > [5] https://lore.kernel.org/lkml/20190910115527.5235-6-kpsingh@chromium.org/ > > > Another reason to have multiple different attach types/contexts (cf. > landlock_domain->programs[]) is to limit useless BPF program > interpretation (in addition to the non-system-wide scoped of programs). > It also enables to handle and verify strict context use (which is also > explain in the Guiding principles). It would be a huge wast of time to > run every BPF programs for all LSM hooks. KRSI does the same but instead > of relying on the program type it rely on the list tied to the > securityfs file. > > BTF is great, but as far as I know, it's goal is to easily deal with the > moving kernel ABI (e.g. task_struct layout, config/constant variables), > and it is definitely useful to programs using bpf_probe_read() and > similar accessors. However, I don't see how KRSI would avoid BPF types > thanks to BTF. > This should become clearer once we post our updated patch-set. Do note that I am currently traveling and will be away for the next couple of weeks. > There is only one program type for Landlock (i.e. > BPF_PROG_TYPE_LANDLOCK_HOOK), and I don't see why adding new program > *attach* types (e.g. BPF_LANDLOCK_PTRACE) may be an issue. The kernel > will still need to be modified to implement new hooks and the new BPF > helpers anyway, BTF will not change that, except maybe if the internal > LSM API is exposed in a way or another to BPF (thanks to BTF), which > does not seem acceptable. Am I missing something? > > > The current KRSI approach is to allow a common set of helpers to be > called by all programs (because there is no way to differentiate them > with their type). > How KRSI would deal with kernel objects other than the current task > (e.g. a ptrace hook with a tracer and a tracee, a file open/read) with > the struct krsi_ctx unions [6]? > > [6] https://lore.kernel.org/lkml/20190910115527.5235-7-kpsingh@chromium.org/ > The best part of BTF is that it can provide a common way to pass different contexts to the various attachments points and the verifier can use the BTF information to validate accesses which essentially allows us to change the helpers from: is_running_executable(magical_krsi_ctx) to is_running_executable(inode) which can work on any inode (ARG_PTR_TO_BTF_ID = btf_id(struct inode)) This makes the helpers much more useful and generic. All this is better explained in our upcoming patch-set. > > How does KRSI plan to deal with security blobs? The new prototype uses security blobs but does not expose them to user-space. These blobs are then used in various helpers like “is_running_executable” which uses blobs on the inode and the task_struct. This should become clearer when the next patchset is posted. I don’t think it’s currently possible to allow the blobs to be set using eBPF programs with the main reason being that the blob will only be set after the program is loaded. The answer to “is_running_executable” becomes dependent on whether the file was executed before the blob setting eBPF program was loaded. Blob management with eBPF is not possible unless we can load eBPF programs that can set blobs at boot-time. In short, the next KRSI version will not give eBPF programs access to arbitrarily write security blobs. > > > > > > * These new BPF features also alleviate the original concerns that we > > raised when initially proposing KRSI and designing for precise BPF > > helpers. We have some patches coming up which incorporate these new > > changes and will be sharing something on the mailing list after some > > cleanup. > > > > We can use the common "eBPF+LSM" for both privileged MAC and Audit and > > unprivileged sandboxing i.e. Discretionary Access Control. > > Here's what it could look like: > > > > * Common infrastructure allows attachment to all hooks which works well > > for privileged MAC and Audit. This could be extended to provide > > another attachment type for unprivileged DAC, which can restrict the > > hooks that can be attached to, and also the information that is > > exposed to the eBPF programs which is something that Landlock could > > build. > > I agree that the "privileged-only" hooks should be a superset of the > "security-safe-and-potentially-unprivileged" hooks. :) > However, as said previously, I'm convinced it is a requirement to have > abstract hooks (and associated program attach types) as defined by Landlock. I would like to hear the BPF maintainers’ perspective on this. I am not sure they agree with you here. - KP Singh > > I'm not sure what you mean by "the information that is exposed to the > eBPF program". Is it the current Landlock implementation of specific > contexts and attach types? > > > > > * This attachment could use the proposed landlock domains and attach to > > the task_struct providing the discretionary access control semantics. > > Not task_struct but creds, yes. This is a characteristic of sandboxing, > which may not be useful for the KRSI use case. It makes sense for KRSI > to attach program sets (or Landlock domains) to the whole system, then > using the creds does not make sense here. This difference is small and a > previous version of Landlock already validated this use case with > cgroups [3] (which is postponed to simplify the patch series). > > [3] https://lore.kernel.org/lkml/20160914072415.26021-17-mic@digikod.net/ > > > > > > [1] https://static.sched.com/hosted_files/lsseu2019/a2/Kernel%20Runtime%20Security%20Instrumentation.pdf > > [2] http://vger.kernel.org/bpfconf2019_talks/bpf-core.pdf > > > > - KP Singh > > I think it should be OK to first land something close to this Landlock > patch series and then we could extend the domain management features and > add the securityfs support that KRSI needs. The main concern seems to be > about hook definitions. > > Another approach would be to land Landlock and KRSI as distinct LSM > while trying as much as possible to mutualize code/helpers.
On 06/11/2019 22:45, KP Singh wrote: > On 06-Nov 17:55, Mickaël Salaün wrote: >> >> On 06/11/2019 11:06, KP Singh wrote: >>> On 05-Nov 11:34, Alexei Starovoitov wrote: >>>> On Tue, Nov 05, 2019 at 07:01:41PM +0100, Mickaël Salaün wrote: >>>>> On 05/11/2019 18:18, Alexei Starovoitov wrote: >> >> [...] >> >>>>>> I think the only way bpf-based LSM can land is both landlock and KRSI >>>>>> developers work together on a design that solves all use cases. >>>>> >>>>> As I said in a previous cover letter [1], that would be great. I think >>>>> that the current Landlock bases (almost everything from this series >>>>> except the seccomp interface) should meet both needs, but I would like >>>>> to have the point of view of the KRSI developers. >>>>> >>>>> [1] https://lore.kernel.org/lkml/20191029171505.6650-1-mic@digikod.net/ >>>>> >>>>>> BPF is capable >>>>>> to be a superset of all existing LSMs whereas landlock and KRSI propsals today >>>>>> are custom solutions to specific security concerns. BPF subsystem was extended >>>>>> with custom things in the past. In networking we have lwt, skb, tc, xdp, sk >>>>>> program types with a lot of overlapping functionality. We couldn't figure out >>>>>> how to generalize them into single 'networking' program. Now we can and we >>>>>> should. Accepting two partially overlapping bpf-based LSMs would be repeating >>>>>> the same mistake again. >>>>> >>>>> I'll let the LSM maintainers comment on whether BPF could be a superset >>>>> of all LSM, but given the complexity of an access-control system, I have >>>>> some doubts though. Anyway, we need to start somewhere and then iterate. >>>>> This patch series is a first step. >>>> >>>> I would like KRSI folks to speak up. So far I don't see any sharing happening >>>> between landlock and KRSI. You're claiming this set is a first step. They're >>>> claiming the same about their patches. I'd like to set a patchset that was >>>> jointly developed. >>> >>> We are willing to collaborate with the Landlock developers and come up >>> with a common approach that would work for Landlock and KRSI. I want >>> to mention that this collaboration and the current Landlock approach >>> of using an eBPF based LSM for unprivileged sandboxing only makes sense >>> if unprivileged usage of eBPF is going to be ever allowed. >> >> The ability to *potentially* do unprivileged sandboxing is definitely >> not tied nor a blocker to the unprivileged usage of eBPF. As explained >> in the documentation [1] (cf. Guiding principles / Unprivileged use), >> Landlock is designed to be as safe as possible (from a security point of >> view). The impact is more complex and important than just using >> unprivileged eBPF, which may not be required. Unprivileged use of eBPF >> would be nice, but I think the current direction is to extend the Linux >> capabilities with one or multiple dedicated to eBPF [2] (e.g. CAP_BPF + >> something else), which may be even better (and a huge difference with >> CAP_SYS_ADMIN, a.k.a. privileged mode or root). Landlock is designed to >> deal with unprivileged (i.e. non-root) use cases, but of course, if the >> Landlock architecture may enable to do unprivileged stuff, it definitely >> can do privileged stuff too. However, having an architecture designed >> with safe unprivileged use in mind can't be achieve afterwards. >> >> [1] https://lore.kernel.org/lkml/20191104172146.30797-8-mic@digikod.net/ >> [2] https://lore.kernel.org/bpf/20190827205213.456318-1-ast@kernel.org/ >> >> >>> >>> Purely from a technical standpoint, both the current designs for >>> Landlock and KRSI target separate use cases and it would not be >>> possible to build "one on top of the other". We've tried to identify >>> the lowest denominator ("eBPF+LSM") requirements for both Landlock >>> (unprivileged sandboxing / Discretionary Access Control) and KRSI >>> (flexibility and unification of privileged MAC and Audit) and >>> prototyped an implementation based on the newly added / upcoming >>> features in BPF. >> >> This is not as binary as that. Sandboxing can be seen as DAC but also as >> MAC, depending on the subject which apply the security policy and the >> subjects which are enforced by this policy. If the sandboxing is applied >> system-wide, it is what we usually call MAC. DAC, in the Linux world, >> enables any user to restrict access to their files to other users. >> >> With Landlock it is not the same because a process can restrict itself >> but also enforce these restrictions on all its future children (which >> may be malicious, whatever their UID/GID). The threat and the definition >> of the attacker are not the same in both cases. With the Linux DAC the >> potentially malicious subjects are the other users, whereas with >> Landlock the potentially malicious subjects are (for now) the current >> process and all its children. Another way to explain it, and how >> Landlock is designed, is that a specific enforcement (i.e. a set of BPF >> programs) is tied to a domain, in which a set of subject are. From this >> perspective, this approach (subjects/tasks in a domain) is orthogonal to >> the DAC system (subjects/users). This design may apply to a system-wide >> MAC system by putting all the system tasks in one domain, and managing >> restrictions (by subject) with other means (e.g. task's UID, >> command-line strings, environment variables). In short, Landlock (in >> this patch series) is closer to a (potentially scoped) MAC system. But >> thanks to eBPF, Landlock is firstly a programmatic access-control, which >> means that the one who write the programs and tie them to a set of >> tasks, can implement their own access-control system (e.g. RBAC, >> time-based…), or something else (e.g. an audit system). >> >> The audit part can simply be achieve with dedicated helpers and programs >> that always allow accesses. >> >> Landlock evolved over multiple iterations and is now designed to be very >> flexible. The current way to enforce a security policy is to go through >> the seccomp syscall (which makes sense for multiple reasons explained >> and accepted before). But Landlock is designed to enable similar >> enforcements (or audit) with other ways to define a domain (e.g. cgroups >> [3], or system-wide securityfs as done in KRSI). Indeed, the only part >> tied to this scoped enforcement is in the domain_syscall.c file. A new >> file domain_fs.c could be added to implement a securityfs for a >> system-wide enforcement (and have other features as KRSI does). >> > > Given the current way landlock exposes LSM hooks, I don't think it's > possible to build system-wide detections. Why ? > But let’s try to come to a > consensus on the semantics of the how the LSM hooks are exposed to > BPF. At the moment I think we should: > > > * Bring the core interface exposed to eBPF closer to the LSM surface in > a way that supports both use cases. One way Landlock can still provide > a more abstract interface is by providing some BPF helper libraries > that build on top of the core framework. I still don't get why you think it is the only way or the better. I gave a lot of arguments and I explained why Landlock is designed the way it is, especially in the documentation (Guiding principles). Is there something similar for KRSI? > > * Use a single BPF program type; this is necessary for a key requirement > of KRSI, i.e. runtime instrumentation. The upcoming prototype should > illustrate how this works for KRSI - note that it’s possible to vary > the context types exposed by different hooks. Why a single BPF program type? Do you mean *attach* types? Landlock only use one program type, but will use multiple attach types. Why do you think it is necessary for KRSI or for runtime instrumentation? If it is justified, it could be a dedicated program attach type (e.g. BPF_LANDLOCK_INTROSPECTION). What is the advantage to have the possibility to vary the context types over dedicated *typed* contexts? I don't see any advantages, but at least one main drawback: to require runtime checks (when helpers use this generic context) instead of load time checks (thanks to static type checking of the context). > It would be nice to get the BPF maintainers’ opinion on these points. > > >> [3] https://lore.kernel.org/lkml/20160914072415.26021-17-mic@digikod.net/ >> >> One possible important difference between Landlock and KRSI right now is >> the BPF program management. Both manage a list of programs per hook. >> However KRSI needs to be able to replace a program in these lists. This >> is not implemented in this Landlock patch series, first because it is >> not the main use-case and it is safer to have an append-only way to add >> restrictions (cf. seccomp-bpf model), and second because it is simpler >> to deal with immutable lists. However, it is worth considering extending >> the Landlock domain management with the ability to update the program >> lists. One challenge may be to identify which program should be replaced >> (which KRSI does with the program name). I think it would be wiser to >> implement this in a second step though, maybe not for the syscall >> interface (thanks to a new seccomp operation), but first with the >> securityfs one. >> >> >>> >>> We've been successfully able to prototype the use cases for KRSI >>> (privileged MAC and Audit) using this "eBPF+LSM" and shared our >>> approach at the Linux Security Summit [1]: >>> >>> * Use the new in-kernel BTF (CO-RE eBPF programs) [2] and the ability >>> of the BPF verifier to use the BTF information for access validation >>> to provide a more generic way to attach to the various LSM hooks. >>> This potentially saves a lot of redundant work: >>> >>> - Creation of new program types. >>> - Multiple types of contexts (or a single context with Unions). >>> - Changes to the verifier and creation of new BPF argument types >>> (eg. PTR_TO_TASK) >> >> As I understood from the LSS talk, KRSI's approach is to use the same >> hooks as LSM (cf. the securityfs). As said Alexei [4] "It must not make >> LSM hooks into stable ABI". Moveover, the LSM hooks may change >> according to internal kernel evolution, and their semantic may not make > > I think you misunderstand Alexei here. I will let him elaborate. > >> sense from a user space point of view. This is one reason for which >> Lanlock abstract those hooks into something that is simpler and designed >> to fit well with eBPF (program contexts and their attached types, as >> explained in the documentation). >> >> [4] >> https://lore.kernel.org/lkml/20191105215453.szhdkrvuekwfz6le@ast-mbp.dhcp.thefacebook.com/ >> >> How does KRSI plan to deal with one LSM hook being split in two hooks in >> a next version of the kernel (cf. [5])? > > How often has that happened in the past? And even if it does happen, > it can still be handled as a part of the base framework we are trying > to implement. I guess the security maintainers should have an opinion on this. I don't clearly see the properties of this base framework. Could this be elaborated? >> [5] https://lore.kernel.org/lkml/20190910115527.5235-6-kpsingh@chromium.org/ >> >> >> Another reason to have multiple different attach types/contexts (cf. >> landlock_domain->programs[]) is to limit useless BPF program >> interpretation (in addition to the non-system-wide scoped of programs). >> It also enables to handle and verify strict context use (which is also >> explain in the Guiding principles). It would be a huge wast of time to >> run every BPF programs for all LSM hooks. KRSI does the same but instead >> of relying on the program type it rely on the list tied to the >> securityfs file. >> >> BTF is great, but as far as I know, it's goal is to easily deal with the >> moving kernel ABI (e.g. task_struct layout, config/constant variables), >> and it is definitely useful to programs using bpf_probe_read() and >> similar accessors. However, I don't see how KRSI would avoid BPF types >> thanks to BTF. >> > > This should become clearer once we post our updated patch-set. Do note > that I am currently traveling and will be away for the next couple of > weeks. > >> There is only one program type for Landlock (i.e. >> BPF_PROG_TYPE_LANDLOCK_HOOK), and I don't see why adding new program >> *attach* types (e.g. BPF_LANDLOCK_PTRACE) may be an issue. The kernel >> will still need to be modified to implement new hooks and the new BPF >> helpers anyway, BTF will not change that, except maybe if the internal >> LSM API is exposed in a way or another to BPF (thanks to BTF), which >> does not seem acceptable. Am I missing something? >> >> >> The current KRSI approach is to allow a common set of helpers to be >> called by all programs (because there is no way to differentiate them >> with their type). >> How KRSI would deal with kernel objects other than the current task >> (e.g. a ptrace hook with a tracer and a tracee, a file open/read) with >> the struct krsi_ctx unions [6]? >> >> [6] https://lore.kernel.org/lkml/20190910115527.5235-7-kpsingh@chromium.org/ >> > > The best part of BTF is that it can provide a common way to pass > different contexts to the various attachments points and the verifier > can use the BTF information to validate accesses which essentially > allows us to change the helpers from: > > is_running_executable(magical_krsi_ctx) > > to > > is_running_executable(inode) > > > which can work on any inode (ARG_PTR_TO_BTF_ID = btf_id(struct inode)) > > This makes the helpers much more useful and generic. All this is > better explained in our upcoming patch-set. I get the usefulness of BTF for future helper evolution and for moving kernel API, but again, I don't see advantages over static typing check of (well abstract/generic) kernel object handles in the context. For instance, how BTF would replace the current BPF_LANDLOCK_PTRACE context and the associated helper? Does this mean that the KRSI v1 design is outdated and superseded by the (future) v2 because of the more important use of BTF? >> How does KRSI plan to deal with security blobs? > > The new prototype uses security blobs but does not expose them to > user-space. These blobs are then used in various helpers like > “is_running_executable” which uses blobs on the inode and the > task_struct. This should become clearer when the next patchset is > posted. > > I don’t think it’s currently possible to allow the blobs to be set > using eBPF programs with the main reason being that the blob will only > be set after the program is loaded. The answer to > “is_running_executable” becomes dependent on whether the file was > executed before the blob setting eBPF program was loaded. > > Blob management with eBPF is not possible unless we can load eBPF > programs that can set blobs at boot-time. > In short, the next KRSI version will not give eBPF > programs access to arbitrarily write security blobs. A previous version of Landlock enabled programs to tag inodes (cf. FS_GET): https://lore.kernel.org/lkml/20180227004121.3633-8-mic@digikod.net/ >>> >>> * These new BPF features also alleviate the original concerns that we >>> raised when initially proposing KRSI and designing for precise BPF >>> helpers. We have some patches coming up which incorporate these new >>> changes and will be sharing something on the mailing list after some >>> cleanup. >>> >>> We can use the common "eBPF+LSM" for both privileged MAC and Audit and >>> unprivileged sandboxing i.e. Discretionary Access Control. >>> Here's what it could look like: >>> >>> * Common infrastructure allows attachment to all hooks which works well >>> for privileged MAC and Audit. This could be extended to provide >>> another attachment type for unprivileged DAC, which can restrict the >>> hooks that can be attached to, and also the information that is >>> exposed to the eBPF programs which is something that Landlock could >>> build. >> >> I agree that the "privileged-only" hooks should be a superset of the >> "security-safe-and-potentially-unprivileged" hooks. :) >> However, as said previously, I'm convinced it is a requirement to have >> abstract hooks (and associated program attach types) as defined by Landlock. > > I would like to hear the BPF maintainers’ perspective on this. I am > not sure they agree with you here. > > - KP Singh > >> >> I'm not sure what you mean by "the information that is exposed to the >> eBPF program". Is it the current Landlock implementation of specific >> contexts and attach types? …or does BTF could magically solve this? >> >>> >>> * This attachment could use the proposed landlock domains and attach to >>> the task_struct providing the discretionary access control semantics. >> >> Not task_struct but creds, yes. This is a characteristic of sandboxing, >> which may not be useful for the KRSI use case. It makes sense for KRSI >> to attach program sets (or Landlock domains) to the whole system, then >> using the creds does not make sense here. This difference is small and a >> previous version of Landlock already validated this use case with >> cgroups [3] (which is postponed to simplify the patch series). >> >> [3] https://lore.kernel.org/lkml/20160914072415.26021-17-mic@digikod.net/ >> >> >>> >>> [1] https://static.sched.com/hosted_files/lsseu2019/a2/Kernel%20Runtime%20Security%20Instrumentation.pdf >>> [2] http://vger.kernel.org/bpfconf2019_talks/bpf-core.pdf >>> >>> - KP Singh >> >> I think it should be OK to first land something close to this Landlock >> patch series and then we could extend the domain management features and >> add the securityfs support that KRSI needs. The main concern seems to be >> about hook definitions. >> >> Another approach would be to land Landlock and KRSI as distinct LSM >> while trying as much as possible to mutualize code/helpers. >
On 11/8/19 3:08 PM, Mickaël Salaün wrote: > On 06/11/2019 22:45, KP Singh wrote: >> On 06-Nov 17:55, Mickaël Salaün wrote: >>> On 06/11/2019 11:06, KP Singh wrote: >>>> On 05-Nov 11:34, Alexei Starovoitov wrote: >>>>> On Tue, Nov 05, 2019 at 07:01:41PM +0100, Mickaël Salaün wrote: >>>>>> On 05/11/2019 18:18, Alexei Starovoitov wrote: [...] >> * Use a single BPF program type; this is necessary for a key requirement >> of KRSI, i.e. runtime instrumentation. The upcoming prototype should >> illustrate how this works for KRSI - note that it’s possible to vary >> the context types exposed by different hooks. > > Why a single BPF program type? Do you mean *attach* types? Landlock only > use one program type, but will use multiple attach types. > > Why do you think it is necessary for KRSI or for runtime instrumentation? > > If it is justified, it could be a dedicated program attach type (e.g. > BPF_LANDLOCK_INTROSPECTION). > > What is the advantage to have the possibility to vary the context types > over dedicated *typed* contexts? I don't see any advantages, but at > least one main drawback: to require runtime checks (when helpers use > this generic context) instead of load time checks (thanks to static type > checking of the context). Lets take security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) as one specific example here: the running kernel has its own internal btf_vmlinux and therefore a complete description of itself. From verifier side we can retrieve & introspect the security_sock_rcv_skb signatue and thus know that the given BPF attachment point has struct sock and struct sk_buff as input arguments which can then be accessed generically by the prog in order to allow sk_filter_trim_cap() to pass or to drop the skb. The same generic approach can be done for many of the other lsm hooks, so single program type would be enough there and context is derived automatically, no dedicated extra context per attach type would be needed and no runtime checks as you mentioned above since its still all asserted at verification time. Thanks, Daniel
On 08-Nov 15:08, Mickaël Salaün wrote: > > On 06/11/2019 22:45, KP Singh wrote: > > On 06-Nov 17:55, Mickaël Salaün wrote: > >> > >> On 06/11/2019 11:06, KP Singh wrote: > >>> On 05-Nov 11:34, Alexei Starovoitov wrote: > >>>> On Tue, Nov 05, 2019 at 07:01:41PM +0100, Mickaël Salaün wrote: > >>>>> On 05/11/2019 18:18, Alexei Starovoitov wrote: > >> > >> [...] > >> > >>>>>> I think the only way bpf-based LSM can land is both landlock and KRSI > >>>>>> developers work together on a design that solves all use cases. > >>>>> > >>>>> As I said in a previous cover letter [1], that would be great. I think > >>>>> that the current Landlock bases (almost everything from this series > >>>>> except the seccomp interface) should meet both needs, but I would like > >>>>> to have the point of view of the KRSI developers. > >>>>> > >>>>> [1] https://lore.kernel.org/lkml/20191029171505.6650-1-mic@digikod.net/ > >>>>> > >>>>>> BPF is capable > >>>>>> to be a superset of all existing LSMs whereas landlock and KRSI propsals today > >>>>>> are custom solutions to specific security concerns. BPF subsystem was extended > >>>>>> with custom things in the past. In networking we have lwt, skb, tc, xdp, sk > >>>>>> program types with a lot of overlapping functionality. We couldn't figure out > >>>>>> how to generalize them into single 'networking' program. Now we can and we > >>>>>> should. Accepting two partially overlapping bpf-based LSMs would be repeating > >>>>>> the same mistake again. > >>>>> > >>>>> I'll let the LSM maintainers comment on whether BPF could be a superset > >>>>> of all LSM, but given the complexity of an access-control system, I have > >>>>> some doubts though. Anyway, we need to start somewhere and then iterate. > >>>>> This patch series is a first step. > >>>> > >>>> I would like KRSI folks to speak up. So far I don't see any sharing happening > >>>> between landlock and KRSI. You're claiming this set is a first step. They're > >>>> claiming the same about their patches. I'd like to set a patchset that was > >>>> jointly developed. > >>> > >>> We are willing to collaborate with the Landlock developers and come up > >>> with a common approach that would work for Landlock and KRSI. I want > >>> to mention that this collaboration and the current Landlock approach > >>> of using an eBPF based LSM for unprivileged sandboxing only makes sense > >>> if unprivileged usage of eBPF is going to be ever allowed. > >> > >> The ability to *potentially* do unprivileged sandboxing is definitely > >> not tied nor a blocker to the unprivileged usage of eBPF. As explained > >> in the documentation [1] (cf. Guiding principles / Unprivileged use), > >> Landlock is designed to be as safe as possible (from a security point of > >> view). The impact is more complex and important than just using > >> unprivileged eBPF, which may not be required. Unprivileged use of eBPF > >> would be nice, but I think the current direction is to extend the Linux > >> capabilities with one or multiple dedicated to eBPF [2] (e.g. CAP_BPF + > >> something else), which may be even better (and a huge difference with > >> CAP_SYS_ADMIN, a.k.a. privileged mode or root). Landlock is designed to > >> deal with unprivileged (i.e. non-root) use cases, but of course, if the > >> Landlock architecture may enable to do unprivileged stuff, it definitely > >> can do privileged stuff too. However, having an architecture designed > >> with safe unprivileged use in mind can't be achieve afterwards. > >> > >> [1] https://lore.kernel.org/lkml/20191104172146.30797-8-mic@digikod.net/ > >> [2] https://lore.kernel.org/bpf/20190827205213.456318-1-ast@kernel.org/ > >> > >> > >>> > >>> Purely from a technical standpoint, both the current designs for > >>> Landlock and KRSI target separate use cases and it would not be > >>> possible to build "one on top of the other". We've tried to identify > >>> the lowest denominator ("eBPF+LSM") requirements for both Landlock > >>> (unprivileged sandboxing / Discretionary Access Control) and KRSI > >>> (flexibility and unification of privileged MAC and Audit) and > >>> prototyped an implementation based on the newly added / upcoming > >>> features in BPF. > >> > >> This is not as binary as that. Sandboxing can be seen as DAC but also as > >> MAC, depending on the subject which apply the security policy and the > >> subjects which are enforced by this policy. If the sandboxing is applied > >> system-wide, it is what we usually call MAC. DAC, in the Linux world, > >> enables any user to restrict access to their files to other users. > >> > >> With Landlock it is not the same because a process can restrict itself > >> but also enforce these restrictions on all its future children (which > >> may be malicious, whatever their UID/GID). The threat and the definition > >> of the attacker are not the same in both cases. With the Linux DAC the > >> potentially malicious subjects are the other users, whereas with > >> Landlock the potentially malicious subjects are (for now) the current > >> process and all its children. Another way to explain it, and how > >> Landlock is designed, is that a specific enforcement (i.e. a set of BPF > >> programs) is tied to a domain, in which a set of subject are. From this > >> perspective, this approach (subjects/tasks in a domain) is orthogonal to > >> the DAC system (subjects/users). This design may apply to a system-wide > >> MAC system by putting all the system tasks in one domain, and managing > >> restrictions (by subject) with other means (e.g. task's UID, > >> command-line strings, environment variables). In short, Landlock (in > >> this patch series) is closer to a (potentially scoped) MAC system. But > >> thanks to eBPF, Landlock is firstly a programmatic access-control, which > >> means that the one who write the programs and tie them to a set of > >> tasks, can implement their own access-control system (e.g. RBAC, > >> time-based…), or something else (e.g. an audit system). > >> > >> The audit part can simply be achieve with dedicated helpers and programs > >> that always allow accesses. > >> > >> Landlock evolved over multiple iterations and is now designed to be very > >> flexible. The current way to enforce a security policy is to go through > >> the seccomp syscall (which makes sense for multiple reasons explained > >> and accepted before). But Landlock is designed to enable similar > >> enforcements (or audit) with other ways to define a domain (e.g. cgroups > >> [3], or system-wide securityfs as done in KRSI). Indeed, the only part > >> tied to this scoped enforcement is in the domain_syscall.c file. A new > >> file domain_fs.c could be added to implement a securityfs for a > >> system-wide enforcement (and have other features as KRSI does). > >> > > > > Given the current way landlock exposes LSM hooks, I don't think it's > > possible to build system-wide detections. > > Why ? This and some of the other questions (about the core-framework and guiding principles) are better discussed in the context of the new-patchset. It might take us some-time as I am on vacation for the next few weeks and some of the other members are traveling. > > > > But let’s try to come to a > > consensus on the semantics of the how the LSM hooks are exposed to > > BPF. At the moment I think we should: > > > > > > * Bring the core interface exposed to eBPF closer to the LSM surface in > > a way that supports both use cases. One way Landlock can still provide > > a more abstract interface is by providing some BPF helper libraries > > that build on top of the core framework. > > I still don't get why you think it is the only way or the better. I gave > a lot of arguments and I explained why Landlock is designed the way it > is, especially in the documentation (Guiding principles). Is there > something similar for KRSI? > > > > > > * Use a single BPF program type; this is necessary for a key requirement > > of KRSI, i.e. runtime instrumentation. The upcoming prototype should > > illustrate how this works for KRSI - note that it’s possible to vary > > the context types exposed by different hooks. > > Why a single BPF program type? Do you mean *attach* types? Landlock only > use one program type, but will use multiple attach types. > > Why do you think it is necessary for KRSI or for runtime instrumentation? > > If it is justified, it could be a dedicated program attach type (e.g. > BPF_LANDLOCK_INTROSPECTION). > > What is the advantage to have the possibility to vary the context types > over dedicated *typed* contexts? I don't see any advantages, but at > least one main drawback: to require runtime checks (when helpers use > this generic context) instead of load time checks (thanks to static type > checking of the context). > > > > It would be nice to get the BPF maintainers’ opinion on these points. > > > > > >> [3] https://lore.kernel.org/lkml/20160914072415.26021-17-mic@digikod.net/ > >> > >> One possible important difference between Landlock and KRSI right now is > >> the BPF program management. Both manage a list of programs per hook. > >> However KRSI needs to be able to replace a program in these lists. This > >> is not implemented in this Landlock patch series, first because it is > >> not the main use-case and it is safer to have an append-only way to add > >> restrictions (cf. seccomp-bpf model), and second because it is simpler > >> to deal with immutable lists. However, it is worth considering extending > >> the Landlock domain management with the ability to update the program > >> lists. One challenge may be to identify which program should be replaced > >> (which KRSI does with the program name). I think it would be wiser to > >> implement this in a second step though, maybe not for the syscall > >> interface (thanks to a new seccomp operation), but first with the > >> securityfs one. > >> > >> > >>> > >>> We've been successfully able to prototype the use cases for KRSI > >>> (privileged MAC and Audit) using this "eBPF+LSM" and shared our > >>> approach at the Linux Security Summit [1]: > >>> > >>> * Use the new in-kernel BTF (CO-RE eBPF programs) [2] and the ability > >>> of the BPF verifier to use the BTF information for access validation > >>> to provide a more generic way to attach to the various LSM hooks. > >>> This potentially saves a lot of redundant work: > >>> > >>> - Creation of new program types. > >>> - Multiple types of contexts (or a single context with Unions). > >>> - Changes to the verifier and creation of new BPF argument types > >>> (eg. PTR_TO_TASK) > >> > >> As I understood from the LSS talk, KRSI's approach is to use the same > >> hooks as LSM (cf. the securityfs). As said Alexei [4] "It must not make > >> LSM hooks into stable ABI". Moveover, the LSM hooks may change > >> according to internal kernel evolution, and their semantic may not make > > > > I think you misunderstand Alexei here. I will let him elaborate. > > > >> sense from a user space point of view. This is one reason for which > >> Lanlock abstract those hooks into something that is simpler and designed > >> to fit well with eBPF (program contexts and their attached types, as > >> explained in the documentation). > >> > >> [4] > >> https://lore.kernel.org/lkml/20191105215453.szhdkrvuekwfz6le@ast-mbp.dhcp.thefacebook.com/ > >> > >> How does KRSI plan to deal with one LSM hook being split in two hooks in > >> a next version of the kernel (cf. [5])? > > > > How often has that happened in the past? And even if it does happen, > > it can still be handled as a part of the base framework we are trying > > to implement. > > I guess the security maintainers should have an opinion on this. > > I don't clearly see the properties of this base framework. Could this be > elaborated? > > > >> [5] https://lore.kernel.org/lkml/20190910115527.5235-6-kpsingh@chromium.org/ > >> > >> > >> Another reason to have multiple different attach types/contexts (cf. > >> landlock_domain->programs[]) is to limit useless BPF program > >> interpretation (in addition to the non-system-wide scoped of programs). > >> It also enables to handle and verify strict context use (which is also > >> explain in the Guiding principles). It would be a huge wast of time to > >> run every BPF programs for all LSM hooks. KRSI does the same but instead > >> of relying on the program type it rely on the list tied to the > >> securityfs file. > >> > >> BTF is great, but as far as I know, it's goal is to easily deal with the > >> moving kernel ABI (e.g. task_struct layout, config/constant variables), > >> and it is definitely useful to programs using bpf_probe_read() and > >> similar accessors. However, I don't see how KRSI would avoid BPF types > >> thanks to BTF. > >> > > > > This should become clearer once we post our updated patch-set. Do note > > that I am currently traveling and will be away for the next couple of > > weeks. > > > >> There is only one program type for Landlock (i.e. > >> BPF_PROG_TYPE_LANDLOCK_HOOK), and I don't see why adding new program > >> *attach* types (e.g. BPF_LANDLOCK_PTRACE) may be an issue. The kernel > >> will still need to be modified to implement new hooks and the new BPF > >> helpers anyway, BTF will not change that, except maybe if the internal > >> LSM API is exposed in a way or another to BPF (thanks to BTF), which > >> does not seem acceptable. Am I missing something? > >> > >> > >> The current KRSI approach is to allow a common set of helpers to be > >> called by all programs (because there is no way to differentiate them > >> with their type). > >> How KRSI would deal with kernel objects other than the current task > >> (e.g. a ptrace hook with a tracer and a tracee, a file open/read) with > >> the struct krsi_ctx unions [6]? > >> > >> [6] https://lore.kernel.org/lkml/20190910115527.5235-7-kpsingh@chromium.org/ > >> > > > > The best part of BTF is that it can provide a common way to pass > > different contexts to the various attachments points and the verifier > > can use the BTF information to validate accesses which essentially > > allows us to change the helpers from: > > > > is_running_executable(magical_krsi_ctx) > > > > to > > > > is_running_executable(inode) > > > > > > which can work on any inode (ARG_PTR_TO_BTF_ID = btf_id(struct inode)) > > > > This makes the helpers much more useful and generic. All this is > > better explained in our upcoming patch-set. > > I get the usefulness of BTF for future helper evolution and for moving > kernel API, but again, I don't see advantages over static typing check > of (well abstract/generic) kernel object handles in the context. > > For instance, how BTF would replace the current BPF_LANDLOCK_PTRACE > context and the associated helper? > > Does this mean that the KRSI v1 design is outdated and superseded by the > (future) v2 because of the more important use of BTF? Yes, that's correct and based on the feedback we got on the RFC v1 at the Linux Plumbers 2019. Also, the changes that allow BPF verifier to use the BTF information to validate accesses and dynamically populate the context are very recent and have influenced the design for the next iteration. - KP Singh > > > >> How does KRSI plan to deal with security blobs? > > > > The new prototype uses security blobs but does not expose them to > > user-space. These blobs are then used in various helpers like > > “is_running_executable” which uses blobs on the inode and the > > task_struct. This should become clearer when the next patchset is > > posted. > > > > I don’t think it’s currently possible to allow the blobs to be set > > using eBPF programs with the main reason being that the blob will only > > be set after the program is loaded. The answer to > > “is_running_executable” becomes dependent on whether the file was > > executed before the blob setting eBPF program was loaded. > > > > Blob management with eBPF is not possible unless we can load eBPF > > programs that can set blobs at boot-time. > > In short, the next KRSI version will not give eBPF > > programs access to arbitrarily write security blobs. > > A previous version of Landlock enabled programs to tag inodes (cf. > FS_GET): https://lore.kernel.org/lkml/20180227004121.3633-8-mic@digikod.net/ > > > >>> > >>> * These new BPF features also alleviate the original concerns that we > >>> raised when initially proposing KRSI and designing for precise BPF > >>> helpers. We have some patches coming up which incorporate these new > >>> changes and will be sharing something on the mailing list after some > >>> cleanup. > >>> > >>> We can use the common "eBPF+LSM" for both privileged MAC and Audit and > >>> unprivileged sandboxing i.e. Discretionary Access Control. > >>> Here's what it could look like: > >>> > >>> * Common infrastructure allows attachment to all hooks which works well > >>> for privileged MAC and Audit. This could be extended to provide > >>> another attachment type for unprivileged DAC, which can restrict the > >>> hooks that can be attached to, and also the information that is > >>> exposed to the eBPF programs which is something that Landlock could > >>> build. > >> > >> I agree that the "privileged-only" hooks should be a superset of the > >> "security-safe-and-potentially-unprivileged" hooks. :) > >> However, as said previously, I'm convinced it is a requirement to have > >> abstract hooks (and associated program attach types) as defined by Landlock. > > > > I would like to hear the BPF maintainers’ perspective on this. I am > > not sure they agree with you here. > > > > - KP Singh > > > >> > >> I'm not sure what you mean by "the information that is exposed to the > >> eBPF program". Is it the current Landlock implementation of specific > >> contexts and attach types? > > …or does BTF could magically solve this? > > > >> > >>> > >>> * This attachment could use the proposed landlock domains and attach to > >>> the task_struct providing the discretionary access control semantics. > >> > >> Not task_struct but creds, yes. This is a characteristic of sandboxing, > >> which may not be useful for the KRSI use case. It makes sense for KRSI > >> to attach program sets (or Landlock domains) to the whole system, then > >> using the creds does not make sense here. This difference is small and a > >> previous version of Landlock already validated this use case with > >> cgroups [3] (which is postponed to simplify the patch series). > >> > >> [3] https://lore.kernel.org/lkml/20160914072415.26021-17-mic@digikod.net/ > >> > >> > >>> > >>> [1] https://static.sched.com/hosted_files/lsseu2019/a2/Kernel%20Runtime%20Security%20Instrumentation.pdf > >>> [2] http://vger.kernel.org/bpfconf2019_talks/bpf-core.pdf > >>> > >>> - KP Singh > >> > >> I think it should be OK to first land something close to this Landlock > >> patch series and then we could extend the domain management features and > >> add the securityfs support that KRSI needs. The main concern seems to be > >> about hook definitions. > >> > >> Another approach would be to land Landlock and KRSI as distinct LSM > >> while trying as much as possible to mutualize code/helpers. > >
On 08/11/2019 15:34, Daniel Borkmann wrote: > On 11/8/19 3:08 PM, Mickaël Salaün wrote: >> On 06/11/2019 22:45, KP Singh wrote: >>> On 06-Nov 17:55, Mickaël Salaün wrote: >>>> On 06/11/2019 11:06, KP Singh wrote: >>>>> On 05-Nov 11:34, Alexei Starovoitov wrote: >>>>>> On Tue, Nov 05, 2019 at 07:01:41PM +0100, Mickaël Salaün wrote: >>>>>>> On 05/11/2019 18:18, Alexei Starovoitov wrote: > [...] >>> * Use a single BPF program type; this is necessary for a key requirement >>> of KRSI, i.e. runtime instrumentation. The upcoming prototype should >>> illustrate how this works for KRSI - note that it’s possible to vary >>> the context types exposed by different hooks. >> >> Why a single BPF program type? Do you mean *attach* types? Landlock only >> use one program type, but will use multiple attach types. >> >> Why do you think it is necessary for KRSI or for runtime instrumentation? >> >> If it is justified, it could be a dedicated program attach type (e.g. >> BPF_LANDLOCK_INTROSPECTION). >> >> What is the advantage to have the possibility to vary the context types >> over dedicated *typed* contexts? I don't see any advantages, but at >> least one main drawback: to require runtime checks (when helpers use >> this generic context) instead of load time checks (thanks to static type >> checking of the context). > > Lets take security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) > as one specific example here: the running kernel has its own internal > btf_vmlinux and therefore a complete description of itself. From verifier > side we can retrieve & introspect the security_sock_rcv_skb signatue OK, this is indeed the signature defined by the kernel API. What happen if this API change (e.g. if struct sock is replaced with a struct sock_meta)? > and > thus know that the given BPF attachment point has struct sock and struct > sk_buff as input arguments How does the verifier know a given BPF attachment point for a program without relying on its type or attach type? How and where is registered this mapping? To say it another way, if there is no way to differentiate two program targeting different hook, I don't understand how the verifier could check if a given program can legitimately call a helper which could read the tracer and tracee fields (legitimate for a ptrace hook), whereas this program may be attached to a sock_rcv_skb hook (and there is no way to know that). > which can then be accessed generically by the > prog in order to allow sk_filter_trim_cap() to pass or to drop the skb. > The same generic approach can be done for many of the other lsm hooks, so > single program type would be enough there and context is derived > automatically, > no dedicated extra context per attach type would be needed and no runtime > checks as you mentioned above since its still all asserted at verification > time. I mentioned runtime check because I though a helper should handle the case when it doesn't make sense for a program attached to a specific point/hook (e.g. ptrace) to use an input argument (e.g. sk) defined for another point/hook (e.g. sock_rcv_skb). > > Thanks, > Daniel > Thanks for this explanation Daniel.
diff --git a/security/landlock/Makefile b/security/landlock/Makefile index 0b291f2c027c..93e4c2f31c8a 100644 --- a/security/landlock/Makefile +++ b/security/landlock/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o landlock-y := init.o \ - bpf_verify.o bpf_ptrace.o \ + bpf_verify.o bpf_run.o bpf_ptrace.o \ domain_manage.o domain_syscall.o \ - hooks_cred.o + hooks_cred.o hooks_ptrace.o diff --git a/security/landlock/bpf_run.c b/security/landlock/bpf_run.c new file mode 100644 index 000000000000..454cd4b6e99b --- /dev/null +++ b/security/landlock/bpf_run.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Landlock LSM - eBPF program evaluation + * + * Copyright © 2016-2019 Mickaël Salaün <mic@digikod.net> + * Copyright © 2018-2019 ANSSI + */ + +#include <asm/current.h> +#include <linux/bpf.h> +#include <linux/errno.h> +#include <linux/filter.h> +#include <linux/preempt.h> +#include <linux/rculist.h> +#include <uapi/linux/landlock.h> + +#include "bpf_run.h" +#include "common.h" +#include "hooks_ptrace.h" + +static const void *get_prog_ctx(struct landlock_hook_ctx *hook_ctx) +{ + switch (hook_ctx->type) { + case LANDLOCK_HOOK_PTRACE: + return landlock_get_ctx_ptrace(hook_ctx->ctx_ptrace); + } + WARN_ON(1); + return NULL; +} + +/** + * landlock_access_denied - run Landlock programs tied to a hook + * + * @domain: Landlock domain pointer + * @hook_ctx: non-NULL valid eBPF context pointer + * + * Return true if at least one program return deny, false otherwise. + */ +bool landlock_access_denied(struct landlock_domain *domain, + struct landlock_hook_ctx *hook_ctx) +{ + struct landlock_prog_list *prog_list; + const size_t hook = get_hook_index(hook_ctx->type); + + if (!domain) + return false; + + for (prog_list = domain->programs[hook]; prog_list; + prog_list = prog_list->prev) { + u32 ret; + const void *prog_ctx; + + prog_ctx = get_prog_ctx(hook_ctx); + if (!prog_ctx || WARN_ON(IS_ERR(prog_ctx))) + return true; + preempt_disable(); + rcu_read_lock(); + ret = BPF_PROG_RUN(prog_list->prog, prog_ctx); + rcu_read_unlock(); + preempt_enable(); + if (ret & LANDLOCK_RET_DENY) + return true; + } + return false; +} diff --git a/security/landlock/bpf_run.h b/security/landlock/bpf_run.h new file mode 100644 index 000000000000..3461cbb8ec12 --- /dev/null +++ b/security/landlock/bpf_run.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Landlock LSM - eBPF program evaluation headers + * + * Copyright © 2016-2019 Mickaël Salaün <mic@digikod.net> + * Copyright © 2018-2019 ANSSI + */ + +#ifndef _SECURITY_LANDLOCK_BPF_RUN_H +#define _SECURITY_LANDLOCK_BPF_RUN_H + +#include "common.h" +#include "hooks_ptrace.h" + +struct landlock_hook_ctx { + enum landlock_hook_type type; + union { + struct landlock_hook_ctx_ptrace *ctx_ptrace; + }; +}; + +bool landlock_access_denied(struct landlock_domain *domain, + struct landlock_hook_ctx *hook_ctx); + +#endif /* _SECURITY_LANDLOCK_BPF_RUN_H */ diff --git a/security/landlock/hooks_ptrace.c b/security/landlock/hooks_ptrace.c new file mode 100644 index 000000000000..8e518a472d04 --- /dev/null +++ b/security/landlock/hooks_ptrace.c @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Landlock LSM - ptrace hooks + * + * Copyright © 2017-2019 Mickaël Salaün <mic@digikod.net> + * Copyright © 2019 ANSSI + */ + +#include <asm/current.h> +#include <linux/cred.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/lsm_hooks.h> +#include <linux/sched.h> +#include <uapi/linux/landlock.h> + +#include "bpf_run.h" +#include "common.h" +#include "hooks_ptrace.h" + +struct landlock_hook_ctx_ptrace { + struct landlock_context_ptrace prog_ctx; +}; + +const struct landlock_context_ptrace *landlock_get_ctx_ptrace( + const struct landlock_hook_ctx_ptrace *hook_ctx) +{ + if (WARN_ON(!hook_ctx)) + return NULL; + + return &hook_ctx->prog_ctx; +} + +static int check_ptrace(struct landlock_domain *domain, + struct task_struct *tracer, struct task_struct *tracee) +{ + struct landlock_hook_ctx_ptrace ctx_ptrace = { + .prog_ctx = { + .tracer = (uintptr_t)tracer, + .tracee = (uintptr_t)tracee, + }, + }; + struct landlock_hook_ctx hook_ctx = { + .type = LANDLOCK_HOOK_PTRACE, + .ctx_ptrace = &ctx_ptrace, + }; + + return landlock_access_denied(domain, &hook_ctx) ? -EPERM : 0; +} + +/** + * hook_ptrace_access_check - determine whether the current process may access + * another + * + * @child: the process to be accessed + * @mode: the mode of attachment + * + * If the current task (i.e. tracer) has one or multiple BPF_LANDLOCK_PTRACE + * programs, then run them with the `struct landlock_context_ptrace` context. + * If one of these programs return LANDLOCK_RET_DENY, then deny access with + * -EPERM, else allow it by returning 0. + */ +static int hook_ptrace_access_check(struct task_struct *child, + unsigned int mode) +{ + struct landlock_domain *dom_current; + const size_t hook = get_hook_index(LANDLOCK_HOOK_PTRACE); + + dom_current = landlock_cred(current_cred())->domain; + if (!(dom_current && dom_current->programs[hook])) + return 0; + return check_ptrace(dom_current, current, child); +} + +/** + * hook_ptrace_traceme - determine whether another process may trace the + * current one + * + * @parent: the task proposed to be the tracer + * + * If the parent task (i.e. tracer) has one or multiple BPF_LANDLOCK_PTRACE + * programs, then run them with the `struct landlock_context_ptrace` context. + * If one of these programs return LANDLOCK_RET_DENY, then deny access with + * -EPERM, else allow it by returning 0. + */ +static int hook_ptrace_traceme(struct task_struct *parent) +{ + struct landlock_domain *dom_parent; + const size_t hook = get_hook_index(LANDLOCK_HOOK_PTRACE); + int ret; + + rcu_read_lock(); + dom_parent = landlock_cred(__task_cred(parent))->domain; + if (!(dom_parent && dom_parent->programs[hook])) { + ret = 0; + goto put_rcu; + } + ret = check_ptrace(dom_parent, parent, current); + +put_rcu: + rcu_read_unlock(); + return ret; +} + +static struct security_hook_list landlock_hooks[] = { + LSM_HOOK_INIT(ptrace_access_check, hook_ptrace_access_check), + LSM_HOOK_INIT(ptrace_traceme, hook_ptrace_traceme), +}; + +__init void landlock_add_hooks_ptrace(void) +{ + security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), + LANDLOCK_NAME); +} diff --git a/security/landlock/hooks_ptrace.h b/security/landlock/hooks_ptrace.h new file mode 100644 index 000000000000..53fe651bdb3e --- /dev/null +++ b/security/landlock/hooks_ptrace.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Landlock LSM - ptrace hooks headers + * + * Copyright © 2017-2019 Mickaël Salaün <mic@digikod.net> + * Copyright © 2019 ANSSI + */ + +#ifndef _SECURITY_LANDLOCK_HOOKS_PTRACE_H +#define _SECURITY_LANDLOCK_HOOKS_PTRACE_H + +struct landlock_hook_ctx_ptrace; + +const struct landlock_context_ptrace *landlock_get_ctx_ptrace( + const struct landlock_hook_ctx_ptrace *hook_ctx); + +__init void landlock_add_hooks_ptrace(void); + +#endif /* _SECURITY_LANDLOCK_HOOKS_PTRACE_H */ diff --git a/security/landlock/init.c b/security/landlock/init.c index 8836ec4defd3..541aad17418e 100644 --- a/security/landlock/init.c +++ b/security/landlock/init.c @@ -10,11 +10,13 @@ #include "common.h" #include "hooks_cred.h" +#include "hooks_ptrace.h" static int __init landlock_init(void) { pr_info(LANDLOCK_NAME ": Registering hooks\n"); landlock_add_hooks_cred(); + landlock_add_hooks_ptrace(); return 0; }
Add a first Landlock hook that can be used to enforce a security policy or to audit some process activities. For a sandboxing use-case, it is needed to inform the kernel if a task can legitimately debug another. ptrace(2) can also be used by an attacker to impersonate another task and remain undetected while performing malicious activities. Using ptrace(2) and related features on a target process can lead to a privilege escalation. A sandboxed task must then be able to tell the kernel if another task is more privileged, via ptrace_may_access(). Signed-off-by: Mickaël Salaün <mic@digikod.net> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: James Morris <jmorris@namei.org> Cc: Kees Cook <keescook@chromium.org> Cc: Serge E. Hallyn <serge@hallyn.com> Cc: Will Drewry <wad@chromium.org> --- Changes since v12: * ensure preemption is disabled before running BPF programs, cf. commit 568f196756ad ("bpf: check that BPF programs run with preemption disabled") Changes since v10: * revamp and replace the static policy with a Landlock hook which may be used by the corresponding BPF_LANDLOCK_PTRACE program (attach) type and a dedicated process_cmp_landlock_ptrace() BPF helper * check prog return value against LANDLOCK_RET_DENY (ret is a bitmask) Changes since v6: * factor out ptrace check * constify pointers * cleanup headers * use the new security_add_hooks() --- security/landlock/Makefile | 4 +- security/landlock/bpf_run.c | 65 ++++++++++++++++++ security/landlock/bpf_run.h | 25 +++++++ security/landlock/hooks_ptrace.c | 114 +++++++++++++++++++++++++++++++ security/landlock/hooks_ptrace.h | 19 ++++++ security/landlock/init.c | 2 + 6 files changed, 227 insertions(+), 2 deletions(-) create mode 100644 security/landlock/bpf_run.c create mode 100644 security/landlock/bpf_run.h create mode 100644 security/landlock/hooks_ptrace.c create mode 100644 security/landlock/hooks_ptrace.h