Re: [PATCH bpf-next v8 05/11] seccomp,landlock: Enforce Landlock programs per process hierarchy

2018-04-11 Thread Mickaël Salaün

On 04/10/2018 06:48 AM, Alexei Starovoitov wrote:
> On Mon, Apr 09, 2018 at 12:01:59AM +0200, Mickaël Salaün wrote:
>>
>> On 04/08/2018 11:06 PM, Andy Lutomirski wrote:
>>> On Sun, Apr 8, 2018 at 6:13 AM, Mickaël Salaün <m...@digikod.net> wrote:
>>>>
>>>> On 02/27/2018 10:48 PM, Mickaël Salaün wrote:
>>>>>
>>>>> On 27/02/2018 17:39, Andy Lutomirski wrote:
>>>>>> On Tue, Feb 27, 2018 at 5:32 AM, Alexei Starovoitov
>>>>>> <alexei.starovoi...@gmail.com> wrote:
>>>>>>> On Tue, Feb 27, 2018 at 05:20:55AM +, Andy Lutomirski wrote:
>>>>>>>> On Tue, Feb 27, 2018 at 4:54 AM, Alexei Starovoitov
>>>>>>>> <alexei.starovoi...@gmail.com> wrote:
>>>>>>>>> On Tue, Feb 27, 2018 at 04:40:34AM +, Andy Lutomirski wrote:
>>>>>>>>>> On Tue, Feb 27, 2018 at 2:08 AM, Alexei Starovoitov
>>>>>>>>>> <alexei.starovoi...@gmail.com> wrote:
>>>>>>>>>>> On Tue, Feb 27, 2018 at 01:41:15AM +0100, Mickaël Salaün wrote:
>>>>>>>>>>>> The seccomp(2) syscall can be used by a task to apply a Landlock 
>>>>>>>>>>>> program
>>>>>>>>>>>> to itself. As a seccomp filter, a Landlock program is enforced for 
>>>>>>>>>>>> the
>>>>>>>>>>>> current task and all its future children. A program is immutable 
>>>>>>>>>>>> and a
>>>>>>>>>>>> task can only add new restricting programs to itself, forming a 
>>>>>>>>>>>> list of
>>>>>>>>>>>> programss.
>>>>>>>>>>>>
>>>>>>>>>>>> A Landlock program is tied to a Landlock hook. If the action on a 
>>>>>>>>>>>> kernel
>>>>>>>>>>>> object is allowed by the other Linux security mechanisms (e.g. DAC,
>>>>>>>>>>>> capabilities, other LSM), then a Landlock hook related to this 
>>>>>>>>>>>> kind of
>>>>>>>>>>>> object is triggered. The list of programs for this hook is then
>>>>>>>>>>>> evaluated. Each program return a 32-bit value which can deny the 
>>>>>>>>>>>> action
>>>>>>>>>>>> on a kernel object with a non-zero value. If every programs of the 
>>>>>>>>>>>> list
>>>>>>>>>>>> return zero, then the action on the object is allowed.
>>>>>>>>>>>>
>>>>>>>>>>>> Multiple Landlock programs can be chained to share a 64-bits value 
>>>>>>>>>>>> for a
>>>>>>>>>>>> call chain (e.g. evaluating multiple elements of a file path).  
>>>>>>>>>>>> This
>>>>>>>>>>>> chaining is restricted when a process construct this chain by 
>>>>>>>>>>>> loading a
>>>>>>>>>>>> program, but additional checks are performed when it requests to 
>>>>>>>>>>>> apply
>>>>>>>>>>>> this chain of programs to itself.  The restrictions ensure that it 
>>>>>>>>>>>> is
>>>>>>>>>>>> not possible to call multiple programs in a way that would imply to
>>>>>>>>>>>> handle multiple shared values (i.e. cookies) for one chain.  For 
>>>>>>>>>>>> now,
>>>>>>>>>>>> only a fs_pick program can be chained to the same type of program,
>>>>>>>>>>>> because it may make sense if they have different triggers (cf. next
>>>>>>>>>>>> commits).  This restrictions still allows to reuse Landlock 
>>>>>>>>>>>> programs in
>>>>>>>>>>>> a safe way (e.g. use the same loaded fs_walk program with multiple
>>>>>>>>>>>> chains of fs_pick programs).
>>>>>>>>>>>>
>>>>>>>>>>>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>>&

Re: [PATCH bpf-next v8 05/11] seccomp,landlock: Enforce Landlock programs per process hierarchy

2018-04-08 Thread Mickaël Salaün

On 04/08/2018 11:06 PM, Andy Lutomirski wrote:
> On Sun, Apr 8, 2018 at 6:13 AM, Mickaël Salaün <m...@digikod.net> wrote:
>>
>> On 02/27/2018 10:48 PM, Mickaël Salaün wrote:
>>>
>>> On 27/02/2018 17:39, Andy Lutomirski wrote:
>>>> On Tue, Feb 27, 2018 at 5:32 AM, Alexei Starovoitov
>>>> <alexei.starovoi...@gmail.com> wrote:
>>>>> On Tue, Feb 27, 2018 at 05:20:55AM +, Andy Lutomirski wrote:
>>>>>> On Tue, Feb 27, 2018 at 4:54 AM, Alexei Starovoitov
>>>>>> <alexei.starovoi...@gmail.com> wrote:
>>>>>>> On Tue, Feb 27, 2018 at 04:40:34AM +, Andy Lutomirski wrote:
>>>>>>>> On Tue, Feb 27, 2018 at 2:08 AM, Alexei Starovoitov
>>>>>>>> <alexei.starovoi...@gmail.com> wrote:
>>>>>>>>> On Tue, Feb 27, 2018 at 01:41:15AM +0100, Mickaël Salaün wrote:
>>>>>>>>>> The seccomp(2) syscall can be used by a task to apply a Landlock 
>>>>>>>>>> program
>>>>>>>>>> to itself. As a seccomp filter, a Landlock program is enforced for 
>>>>>>>>>> the
>>>>>>>>>> current task and all its future children. A program is immutable and 
>>>>>>>>>> a
>>>>>>>>>> task can only add new restricting programs to itself, forming a list 
>>>>>>>>>> of
>>>>>>>>>> programss.
>>>>>>>>>>
>>>>>>>>>> A Landlock program is tied to a Landlock hook. If the action on a 
>>>>>>>>>> kernel
>>>>>>>>>> object is allowed by the other Linux security mechanisms (e.g. DAC,
>>>>>>>>>> capabilities, other LSM), then a Landlock hook related to this kind 
>>>>>>>>>> of
>>>>>>>>>> object is triggered. The list of programs for this hook is then
>>>>>>>>>> evaluated. Each program return a 32-bit value which can deny the 
>>>>>>>>>> action
>>>>>>>>>> on a kernel object with a non-zero value. If every programs of the 
>>>>>>>>>> list
>>>>>>>>>> return zero, then the action on the object is allowed.
>>>>>>>>>>
>>>>>>>>>> Multiple Landlock programs can be chained to share a 64-bits value 
>>>>>>>>>> for a
>>>>>>>>>> call chain (e.g. evaluating multiple elements of a file path).  This
>>>>>>>>>> chaining is restricted when a process construct this chain by 
>>>>>>>>>> loading a
>>>>>>>>>> program, but additional checks are performed when it requests to 
>>>>>>>>>> apply
>>>>>>>>>> this chain of programs to itself.  The restrictions ensure that it is
>>>>>>>>>> not possible to call multiple programs in a way that would imply to
>>>>>>>>>> handle multiple shared values (i.e. cookies) for one chain.  For now,
>>>>>>>>>> only a fs_pick program can be chained to the same type of program,
>>>>>>>>>> because it may make sense if they have different triggers (cf. next
>>>>>>>>>> commits).  This restrictions still allows to reuse Landlock programs 
>>>>>>>>>> in
>>>>>>>>>> a safe way (e.g. use the same loaded fs_walk program with multiple
>>>>>>>>>> chains of fs_pick programs).
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>>>>>>>>>
>>>>>>>>> ...
>>>>>>>>>
>>>>>>>>>> +struct landlock_prog_set *landlock_prepend_prog(
>>>>>>>>>> + struct landlock_prog_set *current_prog_set,
>>>>>>>>>> + struct bpf_prog *prog)
>>>>>>>>>> +{
>>>>>>>>>> + struct landlock_prog_set *new_prog_set = current_prog_set;
>>>>>>>>>> + unsigned long pages;
>>>>>>>>>> + int err;
>>>>>>>>>> + size_t i;
>>>>&

Re: [PATCH bpf-next v8 05/11] seccomp,landlock: Enforce Landlock programs per process hierarchy

2018-04-08 Thread Mickaël Salaün

On 02/27/2018 10:48 PM, Mickaël Salaün wrote:
> 
> On 27/02/2018 17:39, Andy Lutomirski wrote:
>> On Tue, Feb 27, 2018 at 5:32 AM, Alexei Starovoitov
>> <alexei.starovoi...@gmail.com> wrote:
>>> On Tue, Feb 27, 2018 at 05:20:55AM +, Andy Lutomirski wrote:
>>>> On Tue, Feb 27, 2018 at 4:54 AM, Alexei Starovoitov
>>>> <alexei.starovoi...@gmail.com> wrote:
>>>>> On Tue, Feb 27, 2018 at 04:40:34AM +, Andy Lutomirski wrote:
>>>>>> On Tue, Feb 27, 2018 at 2:08 AM, Alexei Starovoitov
>>>>>> <alexei.starovoi...@gmail.com> wrote:
>>>>>>> On Tue, Feb 27, 2018 at 01:41:15AM +0100, Mickaël Salaün wrote:
>>>>>>>> The seccomp(2) syscall can be used by a task to apply a Landlock 
>>>>>>>> program
>>>>>>>> to itself. As a seccomp filter, a Landlock program is enforced for the
>>>>>>>> current task and all its future children. A program is immutable and a
>>>>>>>> task can only add new restricting programs to itself, forming a list of
>>>>>>>> programss.
>>>>>>>>
>>>>>>>> A Landlock program is tied to a Landlock hook. If the action on a 
>>>>>>>> kernel
>>>>>>>> object is allowed by the other Linux security mechanisms (e.g. DAC,
>>>>>>>> capabilities, other LSM), then a Landlock hook related to this kind of
>>>>>>>> object is triggered. The list of programs for this hook is then
>>>>>>>> evaluated. Each program return a 32-bit value which can deny the action
>>>>>>>> on a kernel object with a non-zero value. If every programs of the list
>>>>>>>> return zero, then the action on the object is allowed.
>>>>>>>>
>>>>>>>> Multiple Landlock programs can be chained to share a 64-bits value for 
>>>>>>>> a
>>>>>>>> call chain (e.g. evaluating multiple elements of a file path).  This
>>>>>>>> chaining is restricted when a process construct this chain by loading a
>>>>>>>> program, but additional checks are performed when it requests to apply
>>>>>>>> this chain of programs to itself.  The restrictions ensure that it is
>>>>>>>> not possible to call multiple programs in a way that would imply to
>>>>>>>> handle multiple shared values (i.e. cookies) for one chain.  For now,
>>>>>>>> only a fs_pick program can be chained to the same type of program,
>>>>>>>> because it may make sense if they have different triggers (cf. next
>>>>>>>> commits).  This restrictions still allows to reuse Landlock programs in
>>>>>>>> a safe way (e.g. use the same loaded fs_walk program with multiple
>>>>>>>> chains of fs_pick programs).
>>>>>>>>
>>>>>>>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>>>>>>>
>>>>>>> ...
>>>>>>>
>>>>>>>> +struct landlock_prog_set *landlock_prepend_prog(
>>>>>>>> + struct landlock_prog_set *current_prog_set,
>>>>>>>> + struct bpf_prog *prog)
>>>>>>>> +{
>>>>>>>> + struct landlock_prog_set *new_prog_set = current_prog_set;
>>>>>>>> + unsigned long pages;
>>>>>>>> + int err;
>>>>>>>> + size_t i;
>>>>>>>> + struct landlock_prog_set tmp_prog_set = {};
>>>>>>>> +
>>>>>>>> + if (prog->type != BPF_PROG_TYPE_LANDLOCK_HOOK)
>>>>>>>> + return ERR_PTR(-EINVAL);
>>>>>>>> +
>>>>>>>> + /* validate memory size allocation */
>>>>>>>> + pages = prog->pages;
>>>>>>>> + if (current_prog_set) {
>>>>>>>> + size_t i;
>>>>>>>> +
>>>>>>>> + for (i = 0; i < ARRAY_SIZE(current_prog_set->programs); 
>>>>>>>> i++) {
>>>>>>>> + struct landlock_prog_list *walker_p;
>>>>>>>> +
>>>>>>>> + fo

Re: [PATCH bpf-next v8 08/11] landlock: Add ptrace restrictions

2018-04-01 Thread Mickaël Salaün

On 03/06/2018 11:28 PM, Mickaël Salaün wrote:
> 
> On 28/02/2018 01:09, Andy Lutomirski wrote:
>> On Wed, Feb 28, 2018 at 12:00 AM, Mickaël Salaün <m...@digikod.net> wrote:
>>>
>>> On 28/02/2018 00:23, Andy Lutomirski wrote:
>>>> On Tue, Feb 27, 2018 at 11:02 PM, Andy Lutomirski <l...@kernel.org> wrote:
>>>>> On Tue, Feb 27, 2018 at 10:14 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>>>>>
>>>>>
>>>>> I think you're wrong here.  Any sane container trying to use Landlock
>>>>> like this would also create a PID namespace.  Problem solved.  I still
>>>>> think you should drop this patch.
>>>
>>> Containers is one use case, another is build-in sandboxing (e.g. for web
>>> browser…) and another one is for sandbox managers (e.g. Firejail,
>>> Bubblewrap, Flatpack…). In some of these use cases, especially from a
>>> developer point of view, you may want/need to debug your applications
>>> (without requiring to be root). For nested Landlock access-controls
>>> (e.g. container + user session + web browser), it may not be allowed to
>>> create a PID namespace, but you still want to have a meaningful
>>> access-control.
>>>
>>
>> The consideration should be exactly the same as for normal seccomp.
>> If I'm in a container (using PID namespaces + seccomp) and a run a web
>> browser, I can debug the browser.
>>
>> If there's a real use case for adding this type of automatic ptrace
>> protection, then by all means, let's add it as a general seccomp
>> feature.
>>
> 
> Right, it makes sense to add this feature to seccomp filters as well.
> What do you think Kees?
> 

As a second though, it may be useful for seccomp but it should be
another patch series, independent from this one.

The idea to keep in mind is that this ptrace restriction is an automatic
way to define what is called a subject in common access control
vocabulary, like used by SELinux. A subject should not be able to
impersonate another one with less restrictions (to get more rights).
Because of the stackable restrictions of Landlock (same principle used
by seccomp), it is easy to identify which subject (i.e. group of
processes) is more restricted (or with different restrictions) than
another. This follow the same principle as Yama's ptrace_scope.

Another important argument for a different ptrace-protection
mechanism than seccomp is that Landlock programs may be applied (i.e.
define subject) otherwise than with a process hierarchy. Another way to
define a Landlock subject may be by using cgroups (which was previously
discussed). I'm also thinking about being able to create (real)
capabilities (not to be confused with POSIX capabilities), which may be
useful to implement some parts of Capsicum, by attaching Landlock
programs to a file descriptor (and not directly to a group of
processes). All this to highlight that the ptrace protection is specific
to Landlock and may not be directly shared with seccomp.

Even if Landlock follows the footprints of seccomp, they are different
beasts.



signature.asc
Description: OpenPGP digital signature


[PATCH bpf-next v8 00/11] Landlock LSM: Toward unprivileged sandboxing

2018-04-01 Thread Mickaël Salaün

On 03/09/2018 12:53 AM, Andy Lutomirski wrote:
> On Thu, Mar 8, 2018 at 11:51 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>
>> On 07/03/2018 02:21, Andy Lutomirski wrote:
>>> On Tue, Mar 6, 2018 at 11:06 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>>>
>>>> On 06/03/2018 23:46, Tycho Andersen wrote:
>>>>> On Tue, Mar 06, 2018 at 10:33:17PM +, Andy Lutomirski wrote:
>>>>>>>> Suppose I'm writing a container manager.  I want to run "mount" in the
>>>>>>>> container, but I don't want to allow moun() in general and I want to
>>>>>>>> emulate certain mount() actions.  I can write a filter that catches
>>>>>>>> mount using seccomp and calls out to the container manager for help.
>>>>>>>> This isn't theoretical -- Tycho wants *exactly* this use case to be
>>>>>>>> supported.
>>>>>>>
>>>>>>> Well, I think this use case should be handled with something like
>>>>>>> LD_PRELOAD and a helper library. FYI, I did something like this:
>>>>>>> https://github.com/stemjail/stemshim
>>>>>>
>>>>>> I doubt that will work for containers.  Containers that use user
>>>>>> namespaces and, for example, setuid programs aren't going to honor
>>>>>> LD_PRELOAD.
>>>>>
>>>>> Or anything that calls syscalls directly, like go programs.
>>>>
>>>> That's why the vDSO-like approach. Enforcing an access control is not
>>>> the issue here, patching a buggy userland (without patching its code) is
>>>> the issue isn't it?
>>>>
>>>> As far as I remember, the main problem is to handle file descriptors
>>>> while "emulating" the kernel behavior. This can be done with a "shim"
>>>> code mapped in every processes. Chrome used something like this (in a
>>>> previous sandbox mechanism) as a kind of emulation (with the current
>>>> seccomp-bpf ). I think it should be doable to replace the (userland)
>>>> emulation code with an IPC wrapper receiving file descriptors through
>>>> UNIX socket.
>>>>
>>>
>>> Can you explain exactly what you mean by "vDSO-like"?
>>>
>>> When a 64-bit program does a syscall, it just executes the SYSCALL
>>> instruction.  The vDSO isn't involved at all.  32-bit programs usually
>>> go through the vDSO, but not always.
>>>
>>> It could be possible to force-load a DSO into an entire container and
>>> rig up seccomp to intercept all SYSCALLs not originating from the DSO
>>> such that they merely redirect control to the DSO, but that seems
>>> quite messy.
>>
>> vDSO is a code mapped for all processes. As you said, these processes
>> may use it or not. What I was thinking about is to use the same concept,
>> i.e. map a "shim" code into each processes pertaining to a particular
>> hierarchy (the same way seccomp filters are inherited across processes).
>> With a seccomp filter matching some syscall (e.g. mount, open), it is
>> possible to jump back to the shim code thanks to SECCOMP_RET_TRAP. This
>> shim code should then be able to emulate/patch what is needed, even
>> faking a file opening by receiving a file descriptor through a UNIX
>> socket. As did the Chrome sandbox, the seccomp filter may look at the
>> calling address to allow the shim code to call syscalls without being
>> catched, if needed. However, relying on SIGSYS may not fit with
>> arbitrary code. Using a new SECCOMP_RET_EMULATE (?) may be used to jump
>> to a specific process address, to emulate the syscall in an easier way
>> than only relying on a {c,e}BPF program.
>>
> 
> This could indeed be done, but I think that Tycho's approach is much
> cleaner and probably faster.
> 

I like it too but how does this handle file descriptors?



signature.asc
Description: OpenPGP digital signature


Re: [PATCH bpf-next v8 01/11] fs,security: Add a security blob to nameidata

2018-03-11 Thread Mickaël Salaün

On 02/27/2018 02:23 AM, Al Viro wrote:
> On Tue, Feb 27, 2018 at 12:57:21AM +, Al Viro wrote:
>> On Tue, Feb 27, 2018 at 01:41:11AM +0100, Mickaël Salaün wrote:
>>> The function current_nameidata_security(struct inode *) can be used to
>>> retrieve a blob's pointer address tied to the inode being walk through.
>>> This enable to follow a path lookup and know where an inode access come
>>> from. This is needed for the Landlock LSM to be able to restrict access
>>> to file path.
>>>
>>> The LSM hook nameidata_free_security(struct inode *) is called before
>>> freeing the associated nameidata.
>>
>> NAK.  Not without well-defined semantics and "some Linux S uses that for
>> something, don't ask what" does not count.
> 
> Incidentally, pathwalk mechanics is subject to change at zero notice, so
> if you want something, you'd better
>   * have explicitly defined semantics
>   * explain what it is - on fsdevel
>   * not have it hidden behind the layers of opaque LSM dreck, pardon
> the redundance.
> 
> Again, pathwalk internals have changed in the past and may bloody well
> change again in the future.  There's a damn good reason why struct nameidata
> is _not_ visible outside of fs/namei.c, and quietly relying upon any
> implementation details is no-go.
> 

I thought this whole patch series would go to linux-fsdevel but only
this patch did. I'll CCed fsdevel for the next round. Meanwhile, the
cover letter is here: https://lkml.org/lkml/2018/2/26/1214
The code using current_nameidata_lookup(inode) is in the patch 07/11:
https://lkml.org/lkml/2018/2/26/1206

To sum up, I don't know any way to identify if a directory (execute)
access was directly requested by a process or inferred by the kernel
because of a path walk. This was not needed until now because the other
access control systems (either the DAC or access controls enforced by
inode-based LSM, i.e. SELinux and Smack) do not care about the file
hierarchy. Path-based access controls (i.e. AppArmor and Tomoyo)
directly use the notion of path to define a security policy (in the
kernel, not only in the user space configuration). Landlock can't rely
on xattrs (because of composed and unprivileged access control). Because
we can't know for sure from which path an inode come from (if any),
path-based LSM hooks do not help for some file system checks (e.g.
inode_permission). With Landlock, I try to find a way to identify a set
of inodes, from the user space point of view, which is most of the time
related to file hierarchies.

I needed a way to "follow" a path walk, with the minimum amount of code,
and if possible without touching the fs/namei.c . I saw that the
pathwalk mechanism has evolved over time. With this patch, I tried to
make a kernel object (nameidata) usable in some way by LSM, but only
through an inode (current_nameidata_lookup(inode)). The "only" guarantee
of this function should be to identify if an inode is tied to a path
walk. This enable to follow a path walk and know why an inode access is
requested.

I get your concern about the "instability" of the path walk mechanism.
However, I though that a path resolution should not change from the user
space point of view, like other Linux ABI. Anyway, all the current
inode-based access controls, including DAC, rely on this path walks
mechanism. This patch does not expose anything to user space, but only
through the API of Landlock, which is currently relying on path walk
resolutions, already visible to user space. Did I miss something? Do you
have another suggestion to tie an inode to a path walk?

Thanks,
 Mickaël



signature.asc
Description: OpenPGP digital signature


Re: [PATCH bpf-next v8 00/11] Landlock LSM: Toward unprivileged sandboxing

2018-03-08 Thread Mickaël Salaün

On 07/03/2018 02:21, Andy Lutomirski wrote:
> On Tue, Mar 6, 2018 at 11:06 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>
>> On 06/03/2018 23:46, Tycho Andersen wrote:
>>> On Tue, Mar 06, 2018 at 10:33:17PM +, Andy Lutomirski wrote:
>>>>>> Suppose I'm writing a container manager.  I want to run "mount" in the
>>>>>> container, but I don't want to allow moun() in general and I want to
>>>>>> emulate certain mount() actions.  I can write a filter that catches
>>>>>> mount using seccomp and calls out to the container manager for help.
>>>>>> This isn't theoretical -- Tycho wants *exactly* this use case to be
>>>>>> supported.
>>>>>
>>>>> Well, I think this use case should be handled with something like
>>>>> LD_PRELOAD and a helper library. FYI, I did something like this:
>>>>> https://github.com/stemjail/stemshim
>>>>
>>>> I doubt that will work for containers.  Containers that use user
>>>> namespaces and, for example, setuid programs aren't going to honor
>>>> LD_PRELOAD.
>>>
>>> Or anything that calls syscalls directly, like go programs.
>>
>> That's why the vDSO-like approach. Enforcing an access control is not
>> the issue here, patching a buggy userland (without patching its code) is
>> the issue isn't it?
>>
>> As far as I remember, the main problem is to handle file descriptors
>> while "emulating" the kernel behavior. This can be done with a "shim"
>> code mapped in every processes. Chrome used something like this (in a
>> previous sandbox mechanism) as a kind of emulation (with the current
>> seccomp-bpf ). I think it should be doable to replace the (userland)
>> emulation code with an IPC wrapper receiving file descriptors through
>> UNIX socket.
>>
> 
> Can you explain exactly what you mean by "vDSO-like"?
> 
> When a 64-bit program does a syscall, it just executes the SYSCALL
> instruction.  The vDSO isn't involved at all.  32-bit programs usually
> go through the vDSO, but not always.
> 
> It could be possible to force-load a DSO into an entire container and
> rig up seccomp to intercept all SYSCALLs not originating from the DSO
> such that they merely redirect control to the DSO, but that seems
> quite messy.

vDSO is a code mapped for all processes. As you said, these processes
may use it or not. What I was thinking about is to use the same concept,
i.e. map a "shim" code into each processes pertaining to a particular
hierarchy (the same way seccomp filters are inherited across processes).
With a seccomp filter matching some syscall (e.g. mount, open), it is
possible to jump back to the shim code thanks to SECCOMP_RET_TRAP. This
shim code should then be able to emulate/patch what is needed, even
faking a file opening by receiving a file descriptor through a UNIX
socket. As did the Chrome sandbox, the seccomp filter may look at the
calling address to allow the shim code to call syscalls without being
catched, if needed. However, relying on SIGSYS may not fit with
arbitrary code. Using a new SECCOMP_RET_EMULATE (?) may be used to jump
to a specific process address, to emulate the syscall in an easier way
than only relying on a {c,e}BPF program.



signature.asc
Description: OpenPGP digital signature


Re: [PATCH bpf-next v8 00/11] Landlock LSM: Toward unprivileged sandboxing

2018-03-06 Thread Mickaël Salaün

On 06/03/2018 23:46, Tycho Andersen wrote:
> On Tue, Mar 06, 2018 at 10:33:17PM +, Andy Lutomirski wrote:
 Suppose I'm writing a container manager.  I want to run "mount" in the
 container, but I don't want to allow moun() in general and I want to
 emulate certain mount() actions.  I can write a filter that catches
 mount using seccomp and calls out to the container manager for help.
 This isn't theoretical -- Tycho wants *exactly* this use case to be
 supported.
>>>
>>> Well, I think this use case should be handled with something like
>>> LD_PRELOAD and a helper library. FYI, I did something like this:
>>> https://github.com/stemjail/stemshim
>>
>> I doubt that will work for containers.  Containers that use user
>> namespaces and, for example, setuid programs aren't going to honor
>> LD_PRELOAD.
> 
> Or anything that calls syscalls directly, like go programs.

That's why the vDSO-like approach. Enforcing an access control is not
the issue here, patching a buggy userland (without patching its code) is
the issue isn't it?

As far as I remember, the main problem is to handle file descriptors
while "emulating" the kernel behavior. This can be done with a "shim"
code mapped in every processes. Chrome used something like this (in a
previous sandbox mechanism) as a kind of emulation (with the current
seccomp-bpf ). I think it should be doable to replace the (userland)
emulation code with an IPC wrapper receiving file descriptors through
UNIX socket.



signature.asc
Description: OpenPGP digital signature


Re: [PATCH bpf-next v8 08/11] landlock: Add ptrace restrictions

2018-03-06 Thread Mickaël Salaün

On 28/02/2018 01:09, Andy Lutomirski wrote:
> On Wed, Feb 28, 2018 at 12:00 AM, Mickaël Salaün <m...@digikod.net> wrote:
>>
>> On 28/02/2018 00:23, Andy Lutomirski wrote:
>>> On Tue, Feb 27, 2018 at 11:02 PM, Andy Lutomirski <l...@kernel.org> wrote:
>>>> On Tue, Feb 27, 2018 at 10:14 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>>>>
>>>>
>>>> I think you're wrong here.  Any sane container trying to use Landlock
>>>> like this would also create a PID namespace.  Problem solved.  I still
>>>> think you should drop this patch.
>>
>> Containers is one use case, another is build-in sandboxing (e.g. for web
>> browser…) and another one is for sandbox managers (e.g. Firejail,
>> Bubblewrap, Flatpack…). In some of these use cases, especially from a
>> developer point of view, you may want/need to debug your applications
>> (without requiring to be root). For nested Landlock access-controls
>> (e.g. container + user session + web browser), it may not be allowed to
>> create a PID namespace, but you still want to have a meaningful
>> access-control.
>>
> 
> The consideration should be exactly the same as for normal seccomp.
> If I'm in a container (using PID namespaces + seccomp) and a run a web
> browser, I can debug the browser.
> 
> If there's a real use case for adding this type of automatic ptrace
> protection, then by all means, let's add it as a general seccomp
> feature.
> 

Right, it makes sense to add this feature to seccomp filters as well.
What do you think Kees?



signature.asc
Description: OpenPGP digital signature


Re: [PATCH bpf-next v8 00/11] Landlock LSM: Toward unprivileged sandboxing

2018-03-06 Thread Mickaël Salaün


On 28/02/2018 00:09, Andy Lutomirski wrote:
> On Tue, Feb 27, 2018 at 10:03 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>
>> On 27/02/2018 05:36, Andy Lutomirski wrote:
>>> On Tue, Feb 27, 2018 at 12:41 AM, Mickaël Salaün <m...@digikod.net> wrote:
>>>> Hi,
>>>>
> 
>>>>
>>>> ## Why use the seccomp(2) syscall?
>>>>
>>>> Landlock use the same semantic as seccomp to apply access rule
>>>> restrictions. It add a new layer of security for the current process
>>>> which is inherited by its children. It makes sense to use an unique
>>>> access-restricting syscall (that should be allowed by seccomp filters)
>>>> which can only drop privileges. Moreover, a Landlock rule could come
>>>> from outside a process (e.g.  passed through a UNIX socket). It is then
>>>> useful to differentiate the creation/load of Landlock eBPF programs via
>>>> bpf(2), from rule enforcement via seccomp(2).
>>>
>>> This seems like a weak argument to me.  Sure, this is a bit different
>>> from seccomp(), and maybe shoving it into the seccomp() multiplexer is
>>> awkward, but surely the bpf() multiplexer is even less applicable.
>>
>> I think using the seccomp syscall is fine, and everyone agreed on it.
>>
> 
> Ah, sorry, I completely misread what you wrote.  My apologies.  You
> can disregard most of my email.
> 
>>
>>>
>>> Also, looking forward, I think you're going to want a bunch of the
>>> stuff that's under consideration as new seccomp features.  Tycho is
>>> working on a "user notifier" feature for seccomp where, in addition to
>>> accepting, rejecting, or kicking to ptrace, you can send a message to
>>> the creator of the filter and wait for a reply.  I think that Landlock
>>> will want exactly the same feature.
>>
>> I don't think why this may be useful at all her. Landlock does not
>> filter at the syscall level but handles kernel object and actions as
>> does an LSM. That is the whole purpose of Landlock.
> 
> Suppose I'm writing a container manager.  I want to run "mount" in the
> container, but I don't want to allow moun() in general and I want to
> emulate certain mount() actions.  I can write a filter that catches
> mount using seccomp and calls out to the container manager for help.
> This isn't theoretical -- Tycho wants *exactly* this use case to be
> supported.

Well, I think this use case should be handled with something like
LD_PRELOAD and a helper library. FYI, I did something like this:
https://github.com/stemjail/stemshim

Otherwise, we should think about enabling a process to (dynamically)
extend/patch the vDSO (similar to LD_PRELOAD but at the syscall level
and works with static binaries) for a subset of processes (the same way
seccomp filters are inherited). It may be more powerful and flexible
than extending the kernel/seccomp to patch (buggy?) userland.

> 
> But using seccomp for this is indeed annoying.  It would be nice to
> use Landlock's ability to filter based on the filesystem type, for
> example.  So Tycho could write a Landlock rule like:
> 
> bool filter_mount(...)
> {
>   if (path needs emulation)
> call_user_notifier();
> }
> 
> And it should work.
> 
> This means that, if both seccomp user notifiers and Landlock make it
> upstream, then there should probably be a way to have a user notifier
> bound to a seccomp filter and a set of landlock filters.
> 

Using seccomp filters and Landlock programs may be powerful. However,
for this use case, I think a *post-syscall* vDSO-like (which could get
some data returned by a Landlock program) may be much more flexible
(with less kernel code). What is needed here is a way to know the kernel
semantic (Landlock) and a way to patch userland without patching its
code (vDSO-like).



signature.asc
Description: OpenPGP digital signature


Re: [PATCH bpf-next v8 08/11] landlock: Add ptrace restrictions

2018-02-27 Thread Mickaël Salaün

On 28/02/2018 00:23, Andy Lutomirski wrote:
> On Tue, Feb 27, 2018 at 11:02 PM, Andy Lutomirski <l...@kernel.org> wrote:
>> On Tue, Feb 27, 2018 at 10:14 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>>
>>> On 27/02/2018 06:01, Andy Lutomirski wrote:
>>>>
>>>>
>>>>> On Feb 26, 2018, at 8:17 PM, Andy Lutomirski <l...@amacapital.net> wrote:
>>>>>
>>>>>> On Tue, Feb 27, 2018 at 12:41 AM, Mickaël Salaün <m...@digikod.net> 
>>>>>> wrote:
>>>>>> A landlocked process has less privileges than a non-landlocked process
>>>>>> and must then be subject to additional restrictions when manipulating
>>>>>> processes. To be allowed to use ptrace(2) and related syscalls on a
>>>>>> target process, a landlocked process must have a subset of the target
>>>>>> process' rules.
>>>>>>
>>>>>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>>>>>> Cc: Alexei Starovoitov <a...@kernel.org>
>>>>>> Cc: Andy Lutomirski <l...@amacapital.net>
>>>>>> Cc: Daniel Borkmann <dan...@iogearbox.net>
>>>>>> Cc: David S. Miller <da...@davemloft.net>
>>>>>> Cc: James Morris <james.l.mor...@oracle.com>
>>>>>> Cc: Kees Cook <keesc...@chromium.org>
>>>>>> Cc: Serge E. Hallyn <se...@hallyn.com>
>>>>>> ---
>>>>>>
>>>>>> Changes since v6:
>>>>>> * factor out ptrace check
>>>>>> * constify pointers
>>>>>> * cleanup headers
>>>>>> * use the new security_add_hooks()
>>>>>> ---
>>>>>> security/landlock/Makefile   |   2 +-
>>>>>> security/landlock/hooks_ptrace.c | 124 
>>>>>> +++
>>>>>> security/landlock/hooks_ptrace.h |  11 
>>>>>> security/landlock/init.c |   2 +
>>>>>> 4 files changed, 138 insertions(+), 1 deletion(-)
>>>>>> create mode 100644 security/landlock/hooks_ptrace.c
>>>>>> create mode 100644 security/landlock/hooks_ptrace.h
>>>>>>
>>>>>> diff --git a/security/landlock/Makefile b/security/landlock/Makefile
>>>>>> index d0f532a93b4e..605504d852d3 100644
>>>>>> --- a/security/landlock/Makefile
>>>>>> +++ b/security/landlock/Makefile
>>>>>> @@ -3,4 +3,4 @@ obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o
>>>>>> landlock-y := init.o chain.o task.o \
>>>>>>tag.o tag_fs.o \
>>>>>>enforce.o enforce_seccomp.o \
>>>>>> -   hooks.o hooks_cred.o hooks_fs.o
>>>>>> +   hooks.o hooks_cred.o hooks_fs.o hooks_ptrace.o
>>>>>> diff --git a/security/landlock/hooks_ptrace.c 
>>>>>> b/security/landlock/hooks_ptrace.c
>>>>>> new file mode 100644
>>>>>> index ..f1b977b9c808
>>>>>> --- /dev/null
>>>>>> +++ b/security/landlock/hooks_ptrace.c
>>>>>> @@ -0,0 +1,124 @@
>>>>>> +/*
>>>>>> + * Landlock LSM - ptrace hooks
>>>>>> + *
>>>>>> + * Copyright © 2017 Mickaël Salaün <m...@digikod.net>
>>>>>> + *
>>>>>> + * This program is free software; you can redistribute it and/or modify
>>>>>> + * it under the terms of the GNU General Public License version 2, as
>>>>>> + * published by the Free Software Foundation.
>>>>>> + */
>>>>>> +
>>>>>> +#include 
>>>>>> +#include 
>>>>>> +#include  /* ARRAY_SIZE */
>>>>>> +#include 
>>>>>> +#include  /* struct task_struct */
>>>>>> +#include 
>>>>>> +
>>>>>> +#include "common.h" /* struct landlock_prog_set */
>>>>>> +#include "hooks.h" /* landlocked() */
>>>>>> +#include "hooks_ptrace.h"
>>>>>> +
>>>>>> +static bool progs_are_subset(const struct landlock_prog_set *parent,
>>>>>> +   const struct landlock_prog_set *child)
>>>>>> +{
>>>>>> +   size_t i;
>>>>>> +
>>>>>> +   if (!parent 

Re: [net-next v3 0/2] eBPF seccomp filters

2018-02-27 Thread Mickaël Salaün

On 27/02/2018 05:54, Andy Lutomirski wrote:
> 
> 
>> On Feb 26, 2018, at 8:38 PM, Kees Cook  wrote:
>>
>> On Mon, Feb 26, 2018 at 8:19 PM, Andy Lutomirski  wrote:
 On Feb 26, 2018, at 3:20 PM, Kees Cook  wrote:

 On Mon, Feb 26, 2018 at 3:04 PM, Alexei Starovoitov
  wrote:
>> On Mon, Feb 26, 2018 at 07:26:54AM +, Sargun Dhillon wrote:
>> This patchset enables seccomp filters to be written in eBPF. Although, 
>> this
>> [...]
> The main statement I want to hear from seccomp maintainers before
> proceeding any further on this that enabling eBPF in seccomp won't lead
> to seccomp folks arguing against changes in bpf core (like verifier)
> just because it's used by seccomp.
> It must be spelled out in the commit log with explicit Ack.

 The primary thing I'm concerned about with eBPF and seccomp is
 side-effects from eBPF programs running at syscall time. This is an
 extremely sensitive area, and I want to be sure there won't be
 feature-creep here that leads to seccomp getting into a bad state.

 As long as seccomp can continue have its own verifier, I *think* this
 will be fine, though, again I remain concerned about maps, etc. I'm
 still reviewing these patches and how they might provide overlap with
 Tycho's needs too, etc.
>>>
>>> I'm not sure I see this as a huge problem.  As far as I can see, there
>>> are three ways that a verifier change could be problematic:
>>>
>>> 1. Addition of a new type of map.  But seccomp would just not allow
>>> new map types by default, right?
>>>
>>> 2. Addition of a new BPF_CALLable helper.  Seccomp wants a way to
>>> whitelist BPF_CALL targets.  That should be straightforward.
>>
>> Yup, agreed on 1 and 2.
>>
>>> 3. Straight-up bugs.  Those are exactly as problematic as verifier
>>> bugs in any other unprivileged eBPF program type, right?  I don't see
>>> why seccomp is special here.
>>
>> My concern is more about unintended design mistakes or other feature
>> creep with side-effects, especially when it comes to privileges and
>> synchronization. Getting no-new-privs done correctly, for example,
>> took some careful thought and discussion, and I'm shy from how painful
>> TSYNC was on the process locking side, and eBPF has had some rather
>> ugly flaws in the past (and recently: it was nice to be able to say
>> for Spectre that seccomp filters couldn't be constructed to make
>> attacks but eBPF could). Adding the complexity needs to be worth the
>> gain. I'm on board for doing it, I just want to be careful. :)
>>
> 
> I agree.  I think that, if we do this right, we get a clean version of 
> Tycho's notifiers.  We can also very easily build on that to send a 
> non-blocking message to the notifier fd, which gets us a version of seccomp 
> logging that works for things like Chromium and even strace.  I think this is 
> worth it.
> 
> I also think this sort of argument is why Mickaël's privileged-first Landlock 
> is the wrong approach.  By getting the unprivileged parts right from day one, 
> we can carefully extend the mechanism and keep it usable by unprivileged 
> apps.  But, if we'd started as root-only, fixing up everything needed to make 
> it safe for unprivileged users after the fact would have been quite messy.

We agreed (including Kees and you, at the Santa Fe LPC) to limit the use
of Landlock to CAP_SYS_ADMIN at first. It is an artificial limitation
that can be re-enabled by removing three explicit checks/lines. Landlock
was designed for unprivileged use from day one and it is still the goal.

> 
> And the considerations for making eBPF safe for use by unprivileged tasks to 
> filter their descendents are more or less the same for seccomp and Landlock.  
> Can we please arrange things so we solve this problem only once?
> 

Landlock is definitely focused on eBPF. It should not be hard to add a
new Landlock program type to mimic the seccomp filter checks (to use
eBPF features like maps), but I'm not sure to get the use case here.



signature.asc
Description: OpenPGP digital signature


Re: [PATCH bpf-next v8 08/11] landlock: Add ptrace restrictions

2018-02-27 Thread Mickaël Salaün


On 27/02/2018 05:17, Andy Lutomirski wrote:
> On Tue, Feb 27, 2018 at 12:41 AM, Mickaël Salaün <m...@digikod.net> wrote:
>> A landlocked process has less privileges than a non-landlocked process
>> and must then be subject to additional restrictions when manipulating
>> processes. To be allowed to use ptrace(2) and related syscalls on a
>> target process, a landlocked process must have a subset of the target
>> process' rules.
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>> Cc: Alexei Starovoitov <a...@kernel.org>
>> Cc: Andy Lutomirski <l...@amacapital.net>
>> Cc: Daniel Borkmann <dan...@iogearbox.net>
>> Cc: David S. Miller <da...@davemloft.net>
>> Cc: James Morris <james.l.mor...@oracle.com>
>> Cc: Kees Cook <keesc...@chromium.org>
>> Cc: Serge E. Hallyn <se...@hallyn.com>
>> ---
>>
>> Changes since v6:
>> * factor out ptrace check
>> * constify pointers
>> * cleanup headers
>> * use the new security_add_hooks()
>> ---
>>  security/landlock/Makefile   |   2 +-
>>  security/landlock/hooks_ptrace.c | 124 
>> +++
>>  security/landlock/hooks_ptrace.h |  11 
>>  security/landlock/init.c |   2 +
>>  4 files changed, 138 insertions(+), 1 deletion(-)
>>  create mode 100644 security/landlock/hooks_ptrace.c
>>  create mode 100644 security/landlock/hooks_ptrace.h
>>
>> diff --git a/security/landlock/Makefile b/security/landlock/Makefile
>> index d0f532a93b4e..605504d852d3 100644
>> --- a/security/landlock/Makefile
>> +++ b/security/landlock/Makefile
>> @@ -3,4 +3,4 @@ obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o
>>  landlock-y := init.o chain.o task.o \
>> tag.o tag_fs.o \
>> enforce.o enforce_seccomp.o \
>> -   hooks.o hooks_cred.o hooks_fs.o
>> +   hooks.o hooks_cred.o hooks_fs.o hooks_ptrace.o
>> diff --git a/security/landlock/hooks_ptrace.c 
>> b/security/landlock/hooks_ptrace.c
>> new file mode 100644
>> index ..f1b977b9c808
>> --- /dev/null
>> +++ b/security/landlock/hooks_ptrace.c
>> @@ -0,0 +1,124 @@
>> +/*
>> + * Landlock LSM - ptrace hooks
>> + *
>> + * Copyright © 2017 Mickaël Salaün <m...@digikod.net>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2, as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include 
>> +#include 
>> +#include  /* ARRAY_SIZE */
>> +#include 
>> +#include  /* struct task_struct */
>> +#include 
>> +
>> +#include "common.h" /* struct landlock_prog_set */
>> +#include "hooks.h" /* landlocked() */
>> +#include "hooks_ptrace.h"
>> +
>> +static bool progs_are_subset(const struct landlock_prog_set *parent,
>> +   const struct landlock_prog_set *child)
>> +{
>> +   size_t i;
>> +
>> +   if (!parent || !child)
>> +   return false;
>> +   if (parent == child)
>> +   return true;
>> +
>> +   for (i = 0; i < ARRAY_SIZE(child->programs); i++) {
> 
> ARRAY_SIZE(child->programs) seems misleading.  Is there no define
> NUM_LANDLOCK_PROG_TYPES or similar?

Yes, there is _LANDLOCK_HOOK_LAST, but this code seems more readable
exactly because it does not require the developer (or the code checking
tools) to know about this static value.



signature.asc
Description: OpenPGP digital signature


Re: [PATCH bpf-next v8 08/11] landlock: Add ptrace restrictions

2018-02-27 Thread Mickaël Salaün

On 27/02/2018 06:01, Andy Lutomirski wrote:
> 
> 
>> On Feb 26, 2018, at 8:17 PM, Andy Lutomirski <l...@amacapital.net> wrote:
>>
>>> On Tue, Feb 27, 2018 at 12:41 AM, Mickaël Salaün <m...@digikod.net> wrote:
>>> A landlocked process has less privileges than a non-landlocked process
>>> and must then be subject to additional restrictions when manipulating
>>> processes. To be allowed to use ptrace(2) and related syscalls on a
>>> target process, a landlocked process must have a subset of the target
>>> process' rules.
>>>
>>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>>> Cc: Alexei Starovoitov <a...@kernel.org>
>>> Cc: Andy Lutomirski <l...@amacapital.net>
>>> Cc: Daniel Borkmann <dan...@iogearbox.net>
>>> Cc: David S. Miller <da...@davemloft.net>
>>> Cc: James Morris <james.l.mor...@oracle.com>
>>> Cc: Kees Cook <keesc...@chromium.org>
>>> Cc: Serge E. Hallyn <se...@hallyn.com>
>>> ---
>>>
>>> Changes since v6:
>>> * factor out ptrace check
>>> * constify pointers
>>> * cleanup headers
>>> * use the new security_add_hooks()
>>> ---
>>> security/landlock/Makefile   |   2 +-
>>> security/landlock/hooks_ptrace.c | 124 
>>> +++
>>> security/landlock/hooks_ptrace.h |  11 
>>> security/landlock/init.c |   2 +
>>> 4 files changed, 138 insertions(+), 1 deletion(-)
>>> create mode 100644 security/landlock/hooks_ptrace.c
>>> create mode 100644 security/landlock/hooks_ptrace.h
>>>
>>> diff --git a/security/landlock/Makefile b/security/landlock/Makefile
>>> index d0f532a93b4e..605504d852d3 100644
>>> --- a/security/landlock/Makefile
>>> +++ b/security/landlock/Makefile
>>> @@ -3,4 +3,4 @@ obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o
>>> landlock-y := init.o chain.o task.o \
>>>tag.o tag_fs.o \
>>>enforce.o enforce_seccomp.o \
>>> -   hooks.o hooks_cred.o hooks_fs.o
>>> +   hooks.o hooks_cred.o hooks_fs.o hooks_ptrace.o
>>> diff --git a/security/landlock/hooks_ptrace.c 
>>> b/security/landlock/hooks_ptrace.c
>>> new file mode 100644
>>> index ..f1b977b9c808
>>> --- /dev/null
>>> +++ b/security/landlock/hooks_ptrace.c
>>> @@ -0,0 +1,124 @@
>>> +/*
>>> + * Landlock LSM - ptrace hooks
>>> + *
>>> + * Copyright © 2017 Mickaël Salaün <m...@digikod.net>
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License version 2, as
>>> + * published by the Free Software Foundation.
>>> + */
>>> +
>>> +#include 
>>> +#include 
>>> +#include  /* ARRAY_SIZE */
>>> +#include 
>>> +#include  /* struct task_struct */
>>> +#include 
>>> +
>>> +#include "common.h" /* struct landlock_prog_set */
>>> +#include "hooks.h" /* landlocked() */
>>> +#include "hooks_ptrace.h"
>>> +
>>> +static bool progs_are_subset(const struct landlock_prog_set *parent,
>>> +   const struct landlock_prog_set *child)
>>> +{
>>> +   size_t i;
>>> +
>>> +   if (!parent || !child)
>>> +   return false;
>>> +   if (parent == child)
>>> +   return true;
>>> +
>>> +   for (i = 0; i < ARRAY_SIZE(child->programs); i++) {
>>
>> ARRAY_SIZE(child->programs) seems misleading.  Is there no define
>> NUM_LANDLOCK_PROG_TYPES or similar?
>>
>>> +   struct landlock_prog_list *walker;
>>> +   bool found_parent = false;
>>> +
>>> +   if (!parent->programs[i])
>>> +   continue;
>>> +   for (walker = child->programs[i]; walker;
>>> +   walker = walker->prev) {
>>> +   if (walker == parent->programs[i]) {
>>> +   found_parent = true;
>>> +   break;
>>> +   }
>>> +   }
>>> +   if (!found_parent)
>>> +   return false;
>>> +   }
>>> +   return true;
>>> +}
>>
>> If you used sec

Re: [PATCH bpf-next v8 00/11] Landlock LSM: Toward unprivileged sandboxing

2018-02-27 Thread Mickaël Salaün

On 27/02/2018 05:36, Andy Lutomirski wrote:
> On Tue, Feb 27, 2018 at 12:41 AM, Mickaël Salaün <m...@digikod.net> wrote:
>> Hi,
>>
>> This eight series is a major revamp of the Landlock design compared to
>> the previous series [1]. This enables more flexibility and granularity
>> of access control with file paths. It is now possible to enforce an
>> access control according to a file hierarchy. Landlock uses the concept
>> of inode and path to identify such hierarchy. In a way, it brings tools
>> to program what is a file hierarchy.
>>
>> There is now three types of Landlock hooks: FS_WALK, FS_PICK and FS_GET.
>> Each of them accepts a dedicated eBPF program, called a Landlock
>> program.  They can be chained to enforce a full access control according
>> to a list of directories or files. The set of actions on a file is well
>> defined (e.g. read, write, ioctl, append, lock, mount...) taking
>> inspiration from the major Linux LSMs and some other access-controls
>> like Capsicum.  These program types are designed to be cache-friendly,
>> which give room for optimizations in the future.
>>
>> The documentation patch contains some kernel documentation and
>> explanations on how to use Landlock.  The compiled documentation and
>> a talk I gave at FOSDEM can be found here: https://landlock.io
>> This patch series can be found in the branch landlock-v8 in this repo:
>> https://github.com/landlock-lsm/linux
>>
>> There is still some minor issues with this patch series but it should
>> demonstrate how powerful this design may be. One of these issues is that
>> it is not a stackable LSM anymore, but the infrastructure management of
>> security blobs should allow to stack it with other LSM [4].
>>
>> This is the first step of the roadmap discussed at LPC [2].  While the
>> intended final goal is to allow unprivileged users to use Landlock, this
>> series allows only a process with global CAP_SYS_ADMIN to load and
>> enforce a rule.  This may help to get feedback and avoid unexpected
>> behaviors.
>>
>> This series can be applied on top of bpf-next, commit 7d72637eb39f
>> ("Merge branch 'x86-jit'").  This can be tested with
>> CONFIG_SECCOMP_FILTER and CONFIG_SECURITY_LANDLOCK.  I would really
>> appreciate constructive comments on the design and the code.
>>
>>
>> # Landlock LSM
>>
>> The goal of this new Linux Security Module (LSM) called Landlock is to
>> allow any process, including unprivileged ones, to create powerful
>> security sandboxes comparable to XNU Sandbox or OpenBSD Pledge. This
>> kind of sandbox is expected to help mitigate the security impact of bugs
>> or unexpected/malicious behaviors in user-space applications.
>>
>> The approach taken is to add the minimum amount of code while still
>> allowing the user-space application to create quite complex access
>> rules.  A dedicated security policy language such as the one used by
>> SELinux, AppArmor and other major LSMs involves a lot of code and is
>> usually permitted to only a trusted user (i.e. root).  On the contrary,
>> eBPF programs already exist and are designed to be safely loaded by
>> unprivileged user-space.
>>
>> This design does not seem too intrusive but is flexible enough to allow
>> a powerful sandbox mechanism accessible by any process on Linux. The use
>> of seccomp and Landlock is more suitable with the help of a user-space
>> library (e.g.  libseccomp) that could help to specify a high-level
>> language to express a security policy instead of raw eBPF programs.
>> Moreover, thanks to the LLVM front-end, it is quite easy to write an
>> eBPF program with a subset of the C language.
>>
>>
>> # Frequently asked questions
>>
>> ## Why is seccomp-bpf not enough?
>>
>> A seccomp filter can access only raw syscall arguments (i.e. the
>> register values) which means that it is not possible to filter according
>> to the value pointed to by an argument, such as a file pathname. As an
>> embryonic Landlock version demonstrated, filtering at the syscall level
>> is complicated (e.g. need to take care of race conditions). This is
>> mainly because the access control checkpoints of the kernel are not at
>> this high-level but more underneath, at the LSM-hook level. The LSM
>> hooks are designed to handle this kind of checks.  Landlock abstracts
>> this approach to leverage the ability of unprivileged users to limit
>> themselves.
>>
>> Cf. section "What it isn't?" in Documentation/prctl/seccomp_filter.txt
>>
>>

Re: [PATCH bpf-next v8 05/11] seccomp,landlock: Enforce Landlock programs per process hierarchy

2018-02-27 Thread Mickaël Salaün

On 27/02/2018 17:39, Andy Lutomirski wrote:
> On Tue, Feb 27, 2018 at 5:32 AM, Alexei Starovoitov
> <alexei.starovoi...@gmail.com> wrote:
>> On Tue, Feb 27, 2018 at 05:20:55AM +, Andy Lutomirski wrote:
>>> On Tue, Feb 27, 2018 at 4:54 AM, Alexei Starovoitov
>>> <alexei.starovoi...@gmail.com> wrote:
>>>> On Tue, Feb 27, 2018 at 04:40:34AM +, Andy Lutomirski wrote:
>>>>> On Tue, Feb 27, 2018 at 2:08 AM, Alexei Starovoitov
>>>>> <alexei.starovoi...@gmail.com> wrote:
>>>>>> On Tue, Feb 27, 2018 at 01:41:15AM +0100, Mickaël Salaün wrote:
>>>>>>> The seccomp(2) syscall can be used by a task to apply a Landlock program
>>>>>>> to itself. As a seccomp filter, a Landlock program is enforced for the
>>>>>>> current task and all its future children. A program is immutable and a
>>>>>>> task can only add new restricting programs to itself, forming a list of
>>>>>>> programss.
>>>>>>>
>>>>>>> A Landlock program is tied to a Landlock hook. If the action on a kernel
>>>>>>> object is allowed by the other Linux security mechanisms (e.g. DAC,
>>>>>>> capabilities, other LSM), then a Landlock hook related to this kind of
>>>>>>> object is triggered. The list of programs for this hook is then
>>>>>>> evaluated. Each program return a 32-bit value which can deny the action
>>>>>>> on a kernel object with a non-zero value. If every programs of the list
>>>>>>> return zero, then the action on the object is allowed.
>>>>>>>
>>>>>>> Multiple Landlock programs can be chained to share a 64-bits value for a
>>>>>>> call chain (e.g. evaluating multiple elements of a file path).  This
>>>>>>> chaining is restricted when a process construct this chain by loading a
>>>>>>> program, but additional checks are performed when it requests to apply
>>>>>>> this chain of programs to itself.  The restrictions ensure that it is
>>>>>>> not possible to call multiple programs in a way that would imply to
>>>>>>> handle multiple shared values (i.e. cookies) for one chain.  For now,
>>>>>>> only a fs_pick program can be chained to the same type of program,
>>>>>>> because it may make sense if they have different triggers (cf. next
>>>>>>> commits).  This restrictions still allows to reuse Landlock programs in
>>>>>>> a safe way (e.g. use the same loaded fs_walk program with multiple
>>>>>>> chains of fs_pick programs).
>>>>>>>
>>>>>>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>>>>>>
>>>>>> ...
>>>>>>
>>>>>>> +struct landlock_prog_set *landlock_prepend_prog(
>>>>>>> + struct landlock_prog_set *current_prog_set,
>>>>>>> + struct bpf_prog *prog)
>>>>>>> +{
>>>>>>> + struct landlock_prog_set *new_prog_set = current_prog_set;
>>>>>>> + unsigned long pages;
>>>>>>> + int err;
>>>>>>> + size_t i;
>>>>>>> + struct landlock_prog_set tmp_prog_set = {};
>>>>>>> +
>>>>>>> + if (prog->type != BPF_PROG_TYPE_LANDLOCK_HOOK)
>>>>>>> + return ERR_PTR(-EINVAL);
>>>>>>> +
>>>>>>> + /* validate memory size allocation */
>>>>>>> + pages = prog->pages;
>>>>>>> + if (current_prog_set) {
>>>>>>> + size_t i;
>>>>>>> +
>>>>>>> + for (i = 0; i < ARRAY_SIZE(current_prog_set->programs); 
>>>>>>> i++) {
>>>>>>> + struct landlock_prog_list *walker_p;
>>>>>>> +
>>>>>>> + for (walker_p = current_prog_set->programs[i];
>>>>>>> + walker_p; walker_p = 
>>>>>>> walker_p->prev)
>>>>>>> + pages += walker_p->prog->pages;
>>>>>>> + }
>>>>>>> + /* count a struct landlock_prog_set if we need to 

[PATCH bpf-next v8 00/11] Landlock LSM: Toward unprivileged sandboxing

2018-02-26 Thread Mickaël Salaün
cgroups hierarchy
  * allow unprivileged processes to attach Landlock eBPF program to
cgroups
* add subtype to eBPF programs:
  * replace Landlock hook identification by custom eBPF program types
with a dedicated subtype field
  * manage fine-grained privileged Landlock programs
  * register Landlock programs for dedicated trigger origins (e.g.
syscall, return from seccomp filter and/or interruption)
* performance and memory optimizations: use an array to access Landlock
  hooks directly but do not duplicated it for each thread
  (seccomp-based)
* allow running Landlock programs without seccomp filter
* fix seccomp-related issues
* remove extra errno bounding check for Landlock programs
* add some examples for optional eBPF functions or context access
  (network related) according to security checks to allow more features
  for privileged programs (e.g. Checmate)


# Changes since v1

* focus on the LSM hooks, not the syscalls:
  * much more simple implementation
  * does not need audit cache tricks to avoid race conditions
  * more simple to use and more generic because using the LSM hook
abstraction directly
  * more efficient because only checking in LSM hooks
  * architecture agnostic
* switch from cBPF to eBPF:
  * new eBPF program types dedicated to Landlock
  * custom functions used by the eBPF program
  * gain some new features (e.g. 10 registers, can load values of
different size, LLVM translator) but only a few functions allowed
and a dedicated map type
  * new context: LSM hook ID, cookie and LSM hook arguments
  * need to set the sysctl kernel.unprivileged_bpf_disable to 0 (default
value) to be able to load hook filters as unprivileged users
* smaller and simpler:
  * no more checker groups but dedicated arraymap of handles
  * simpler userland structs thanks to eBPF functions
* distinctive name: Landlock


[1] https://lkml.kernel.org/r/20170821000933.13024-1-...@digikod.net
[2] https://lkml.kernel.org/r/5828776a.1010...@digikod.net
[3] 
https://lkml.kernel.org/r/1477390454-12553-1-git-send-email-dan...@zonque.org
[4] https://lwn.net/Articles/741963/

Regards,

Mickaël Salaün (11):
  fs,security: Add a security blob to nameidata
  fs,security: Add a new file access type: MAY_CHROOT
  bpf: Add eBPF program subtype and is_valid_subtype() verifier
  bpf,landlock: Define an eBPF program type for Landlock hooks
  seccomp,landlock: Enforce Landlock programs per process hierarchy
  bpf,landlock: Add a new map type: inode
  landlock: Handle filesystem access control
  landlock: Add ptrace restrictions
  bpf: Add a Landlock sandbox example
  bpf,landlock: Add tests for Landlock
  landlock: Add user and kernel documentation for Landlock

 Documentation/security/index.rst   |1 +
 Documentation/security/landlock/index.rst  |   19 +
 Documentation/security/landlock/kernel.rst |  100 +++
 Documentation/security/landlock/user.rst   |  206 +
 MAINTAINERS|   13 +
 fs/namei.c |   39 +
 fs/open.c  |3 +-
 include/linux/bpf.h|   35 +-
 include/linux/bpf_types.h  |6 +
 include/linux/fs.h |1 +
 include/linux/landlock.h   |   61 ++
 include/linux/lsm_hooks.h  |   12 +
 include/linux/namei.h  |   14 +-
 include/linux/seccomp.h|5 +
 include/linux/security.h   |7 +
 include/uapi/linux/bpf.h   |   34 +-
 include/uapi/linux/landlock.h  |  155 
 include/uapi/linux/seccomp.h   |1 +
 kernel/bpf/Makefile|3 +
 kernel/bpf/cgroup.c|6 +-
 kernel/bpf/core.c  |6 +-
 kernel/bpf/helpers.c   |   38 +
 kernel/bpf/inodemap.c  |  318 
 kernel/bpf/syscall.c   |   62 +-
 kernel/bpf/verifier.c  |   44 +-
 kernel/fork.c  |8 +-
 kernel/seccomp.c   |4 +
 kernel/trace/bpf_trace.c   |   15 +-
 net/core/filter.c  |   76 +-
 samples/bpf/Makefile   |4 +
 samples/bpf/bpf_load.c |   85 +-
 samples/bpf/bpf_load.h |7 +
 samples/bpf/cookie_uid_helper_example.c|2 +-
 samples/bpf/fds_example.c  |2 +-
 samples/bpf/landlock1.h|   14 +
 samples/bpf/landlock1_kern.c   |  171 
 samples/bpf/landlock1_user.c   |  164 
 samples/bpf/sock_example.c |3 +-
 samples/bpf/test_cgrp2_attach.c|2 +-
 samples/bpf/test_cgr

[PATCH bpf-next v8 05/11] seccomp,landlock: Enforce Landlock programs per process hierarchy

2018-02-26 Thread Mickaël Salaün
The seccomp(2) syscall can be used by a task to apply a Landlock program
to itself. As a seccomp filter, a Landlock program is enforced for the
current task and all its future children. A program is immutable and a
task can only add new restricting programs to itself, forming a list of
programss.

A Landlock program is tied to a Landlock hook. If the action on a kernel
object is allowed by the other Linux security mechanisms (e.g. DAC,
capabilities, other LSM), then a Landlock hook related to this kind of
object is triggered. The list of programs for this hook is then
evaluated. Each program return a 32-bit value which can deny the action
on a kernel object with a non-zero value. If every programs of the list
return zero, then the action on the object is allowed.

Multiple Landlock programs can be chained to share a 64-bits value for a
call chain (e.g. evaluating multiple elements of a file path).  This
chaining is restricted when a process construct this chain by loading a
program, but additional checks are performed when it requests to apply
this chain of programs to itself.  The restrictions ensure that it is
not possible to call multiple programs in a way that would imply to
handle multiple shared values (i.e. cookies) for one chain.  For now,
only a fs_pick program can be chained to the same type of program,
because it may make sense if they have different triggers (cf. next
commits).  This restrictions still allows to reuse Landlock programs in
a safe way (e.g. use the same loaded fs_walk program with multiple
chains of fs_pick programs).

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andrew Morton <a...@linux-foundation.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
Cc: Will Drewry <w...@chromium.org>
Link: https://lkml.kernel.org/r/c10a503d-5e35-7785-2f3d-25ed8dd63...@digikod.net
---

Changes since v7:
* handle and verify program chains
* split and rename providers.c to enforce.c and enforce_seccomp.c
* rename LANDLOCK_SUBTYPE_* to LANDLOCK_*

Changes since v6:
* rename some functions with more accurate names to reflect that an eBPF
  program for Landlock could be used for something else than a rule
* reword rule "appending" to "prepending" and explain it
* remove the superfluous no_new_privs check, only check global
  CAP_SYS_ADMIN when prepending a Landlock rule (needed for containers)
* create and use {get,put}_seccomp_landlock() (suggested by Kees Cook)
* replace ifdef with static inlined function (suggested by Kees Cook)
* use get_user() (suggested by Kees Cook)
* replace atomic_t with refcount_t (requested by Kees Cook)
* move struct landlock_{rule,events} from landlock.h to common.h
* cleanup headers

Changes since v5:
* remove struct landlock_node and use a similar inheritance mechanisme
  as seccomp-bpf (requested by Andy Lutomirski)
* rename SECCOMP_ADD_LANDLOCK_RULE to SECCOMP_APPEND_LANDLOCK_RULE
* rename file manager.c to providers.c
* add comments
* typo and cosmetic fixes

Changes since v4:
* merge manager and seccomp patches
* return -EFAULT in seccomp(2) when user_bpf_fd is null to easely check
  if Landlock is supported
* only allow a process with the global CAP_SYS_ADMIN to use Landlock
  (will be lifted in the future)
* add an early check to exit as soon as possible if the current process
  does not have Landlock rules

Changes since v3:
* remove the hard link with seccomp (suggested by Andy Lutomirski and
  Kees Cook):
  * remove the cookie which could imply multiple evaluation of Landlock
rules
  * remove the origin field in struct landlock_data
* remove documentation fix (merged upstream)
* rename the new seccomp command to SECCOMP_ADD_LANDLOCK_RULE
* internal renaming
* split commit
* new design to be able to inherit on the fly the parent rules

Changes since v2:
* Landlock programs can now be run without seccomp filter but for any
  syscall (from the process) or interruption
* move Landlock related functions and structs into security/landlock/*
  (to manage cgroups as well)
* fix seccomp filter handling: run Landlock programs for each of their
  legitimate seccomp filter
* properly clean up all seccomp results
* cosmetic changes to ease the understanding
* fix some ifdef
---
 include/linux/landlock.h|  37 
 include/linux/seccomp.h |   5 +
 include/uapi/linux/seccomp.h|   1 +
 kernel/fork.c   |   8 +-
 kernel/seccomp.c|   4 +
 security/landlock/Makefile  |   3 +-
 security/landlock/chain.c   |  39 
 security/landlock/chain.h   |  35 
 security/landlock/common.h  |  53 +
 security/landlock/enforce.c | 386 
 security/landlock/enforce.h |  21 ++
 security/landlock/enforc

[PATCH bpf-next v8 03/11] bpf: Add eBPF program subtype and is_valid_subtype() verifier

2018-02-26 Thread Mickaël Salaün
The goal of the program subtype is to be able to have different static
fine-grained verifications for a unique program type.

The struct bpf_verifier_ops gets a new optional function:
is_valid_subtype(). This new verifier is called at the beginning of the
eBPF program verification to check if the (optional) program subtype is
valid.

The struct bpf_prog_ops gets a new optional function: put_extra(). This
may be used to put extra data.

For now, only Landlock eBPF programs are using a program subtype (see
next commits) but this could be used by other program types in the
future.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Link: https://lkml.kernel.org/r/20160827205559.ga43...@ast-mbp.thefacebook.com
---

Changes since v7:
* rename LANDLOCK_SUBTYPE_* to LANDLOCK_*
* move subtype in bpf_prog_aux and use only one bit for has_subtype
  (suggested by Alexei Starovoitov)
* wrap the prog_subtype with a prog_extra to be able to reference kernel
  pointers:
  * add an optional put_extra() function to struct bpf_prog_ops to be
able to free the pointed data
  * replace all the prog_subtype with prog_extra in the struct
bpf_verifier_ops functions
* remove the ABI field (requested by Alexei Starovoitov)
* rename subtype fields

Changes since v6:
* rename Landlock version to ABI to better reflect its purpose
* fix unsigned integer checks
* fix pointer cast
* constify pointers
* rebase

Changes since v5:
* use a prog_subtype pointer and make it future-proof
* add subtype test
* constify bpf_load_program()'s subtype argument
* cleanup subtype initialization
* rebase

Changes since v4:
* replace the "status" field with "version" (more generic)
* replace the "access" field with "ability" (less confusing)

Changes since v3:
* remove the "origin" field
* add an "option" field
* cleanup comments
---
 include/linux/bpf.h | 17 ++-
 include/uapi/linux/bpf.h| 11 +
 kernel/bpf/cgroup.c |  6 ++-
 kernel/bpf/core.c   |  5 +-
 kernel/bpf/syscall.c| 35 -
 kernel/bpf/verifier.c   | 19 ++--
 kernel/trace/bpf_trace.c| 15 --
 net/core/filter.c   | 76 ++---
 samples/bpf/bpf_load.c  |  3 +-
 samples/bpf/cookie_uid_helper_example.c |  2 +-
 samples/bpf/fds_example.c   |  2 +-
 samples/bpf/sock_example.c  |  3 +-
 samples/bpf/test_cgrp2_attach.c |  2 +-
 samples/bpf/test_cgrp2_attach2.c|  4 +-
 samples/bpf/test_cgrp2_sock.c   |  2 +-
 tools/include/uapi/linux/bpf.h  | 11 +
 tools/lib/bpf/bpf.c | 15 --
 tools/lib/bpf/bpf.h |  8 +--
 tools/lib/bpf/libbpf.c  |  5 +-
 tools/perf/tests/bpf.c  |  2 +-
 tools/testing/selftests/bpf/test_align.c|  2 +-
 tools/testing/selftests/bpf/test_tag.c  |  2 +-
 tools/testing/selftests/bpf/test_verifier.c | 18 ++-
 23 files changed, 200 insertions(+), 65 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 66df387106de..377b2f3519f3 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -200,26 +200,38 @@ bpf_ctx_record_field_size(struct bpf_insn_access_aux 
*aux, u32 size)
aux->ctx_field_size = size;
 }
 
+/* specific data per program type */
+struct bpf_prog_extra {
+   union bpf_prog_subtype subtype;
+   union {
+   struct bpf_prog *previous;
+   } landlock_hook;
+};
+
 struct bpf_prog_ops {
int (*test_run)(struct bpf_prog *prog, const union bpf_attr *kattr,
union bpf_attr __user *uattr);
+   void (*put_extra)(struct bpf_prog_extra *prog_extra);
 };
 
 struct bpf_verifier_ops {
/* return eBPF function prototype for verification */
-   const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id 
func_id);
+   const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id func_id,
+ const struct bpf_prog_extra *prog_extra);
 
/* return true if 'size' wide access at offset 'off' within bpf_context
 * with 'type' (read or write) is allowed
 */
bool (*is_valid_access)(int off, int size, enum bpf_access_type type,
-   struct bpf_insn_access_aux *info);
+   struct bpf_insn_access_aux *info,
+   const struct bpf_prog_extra *prog_extra);
int (*gen_prologue)(struct bpf_insn *insn, bool direct_write,
const struct bpf_prog *prog);
u32 (*convert_ctx_acc

[PATCH bpf-next v8 02/11] fs,security: Add a new file access type: MAY_CHROOT

2018-02-26 Thread Mickaël Salaün
For compatibility reason, MAY_CHROOT is always set with MAY_CHDIR.
However, this new flag enable to differentiate a chdir form a chroot.

This is needed for the Landlock LSM to be able to evaluate a new root
directory.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexander Viro <v...@zeniv.linux.org.uk>
Cc: Casey Schaufler <ca...@schaufler-ca.com>
Cc: James Morris <jmor...@namei.org>
Cc: John Johansen <john.johan...@canonical.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Paul Moore <p...@paul-moore.com>
Cc: "Serge E. Hallyn" <se...@hallyn.com>
Cc: Stephen Smalley <s...@tycho.nsa.gov>
Cc: Tetsuo Handa <penguin-ker...@i-love.sakura.ne.jp>
Cc: linux-fsde...@vger.kernel.org
---
 fs/open.c  | 3 ++-
 include/linux/fs.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/open.c b/fs/open.c
index 7ea118471dce..084d147c0e96 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -489,7 +489,8 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
if (error)
goto out;
 
-   error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
+   error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR |
+   MAY_CHROOT);
if (error)
goto dput_and_out;
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 2a815560fda0..67c62374446c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -90,6 +90,7 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 #define MAY_CHDIR  0x0040
 /* called from RCU mode, don't block */
 #define MAY_NOT_BLOCK  0x0080
+#define MAY_CHROOT 0x0100
 
 /*
  * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
-- 
2.16.2



[PATCH bpf-next v8 04/11] bpf,landlock: Define an eBPF program type for Landlock hooks

2018-02-26 Thread Mickaël Salaün
Add a new type of eBPF program used by Landlock hooks. This type of
program can be chained with the same eBPF program type (according to
subtype rules). A state can be kept with a value available in the
program's context (e.g. named "cookie" for Landlock programs).

This new BPF program type will be registered with the Landlock LSM
initialization.

Add an initial Landlock Kconfig and update the MAINTAINERS file.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---

Changes since v7:
* cosmetic fixes
* rename LANDLOCK_SUBTYPE_* to LANDLOCK_*
* cleanup UAPI definitions and move them from bpf.h to landlock.h
  (suggested by Alexei Starovoitov)
* disable Landlock by default (suggested by Alexei Starovoitov)
* rename BPF_PROG_TYPE_LANDLOCK_{RULE,HOOK}
* update the Kconfig
* update the MAINTAINERS file
* replace the IOCTL, LOCK and FCNTL events with FS_PICK, FS_WALK and
  FS_GET hook types
* add the ability to chain programs with an eBPF program file descriptor
  (i.e. the "previous" field in a Landlock subtype) and keep a state
  with a "cookie" value available from the context
* add a "triggers" subtype bitfield to match specific actions (e.g.
  append, chdir, read...)

Changes since v6:
* add 3 more sub-events: IOCTL, LOCK, FCNTL
  https://lkml.kernel.org/r/2fbc99a6-f190-f335-bd14-04bdeed35...@digikod.net
* rename LANDLOCK_VERSION to LANDLOCK_ABI to better reflect its purpose,
  and move it from landlock.h to common.h
* rename BPF_PROG_TYPE_LANDLOCK to BPF_PROG_TYPE_LANDLOCK_RULE: an eBPF
  program could be used for something else than a rule
* simplify struct landlock_context by removing the arch and syscall_nr fields
* remove all eBPF map functions call, remove ABILITY_WRITE
* refactor bpf_landlock_func_proto() (suggested by Kees Cook)
* constify pointers
* fix doc inclusion

Changes since v5:
* rename file hooks.c to init.c
* fix spelling

Changes since v4:
* merge a minimal (not enabled) LSM code and Kconfig in this commit

Changes since v3:
* split commit
* revamp the landlock_context:
  * add arch, syscall_nr and syscall_cmd (ioctl, fcntl…) to be able to
cross-check action with the event type
  * replace args array with dedicated fields to ease the addition of new
fields
---
 MAINTAINERS |  13 +++
 include/linux/bpf_types.h   |   3 +
 include/uapi/linux/bpf.h|   1 +
 include/uapi/linux/landlock.h   | 155 +++
 security/Kconfig|   1 +
 security/Makefile   |   2 +
 security/landlock/Kconfig   |  18 
 security/landlock/Makefile  |   3 +
 security/landlock/common.h  |  32 +++
 security/landlock/init.c| 180 
 tools/include/uapi/linux/bpf.h  |   1 +
 tools/include/uapi/linux/landlock.h | 155 +++
 12 files changed, 564 insertions(+)
 create mode 100644 include/uapi/linux/landlock.h
 create mode 100644 security/landlock/Kconfig
 create mode 100644 security/landlock/Makefile
 create mode 100644 security/landlock/common.h
 create mode 100644 security/landlock/init.c
 create mode 100644 tools/include/uapi/linux/landlock.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 3bdc260e36b7..ac0809094bae 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7882,6 +7882,19 @@ S:   Maintained
 F: net/l3mdev
 F: include/net/l3mdev.h
 
+LANDLOCK SECURITY MODULE
+M: Mickaël Salaün <m...@digikod.net>
+S: Supported
+F: Documentation/security/landlock/
+F: include/linux/landlock.h
+F: include/uapi/linux/landlock.h
+F: samples/bpf/landlock*
+F: security/landlock/
+F: tools/include/uapi/linux/landlock.h
+F: tools/testing/selftests/landlock/
+K: landlock
+K: LANDLOCK
+
 LANTIQ MIPS ARCHITECTURE
 M: John Crispin <j...@phrozen.org>
 L: linux-m...@linux-mips.org
diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
index 19b8349a3809..0ca019f3ae4a 100644
--- a/include/linux/bpf_types.h
+++ b/include/linux/bpf_types.h
@@ -22,6 +22,9 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_PERF_EVENT, perf_event)
 #ifdef CONFIG_CGROUP_BPF
 BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_DEVICE, cg_dev)
 #endif
+#ifdef CONFIG_SECURITY_LANDLOCK
+BPF_PROG_TYPE(BPF_PROG_TYPE_LANDLOCK_HOOK, landlock)
+#endif
 
 BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY, array_map_ops)
 BPF_MAP_TYPE(BPF_MAP_TYPE_PERCPU_ARRAY, percpu_array_map_ops)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 87885c92ca78..2433aa1a0fd4 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@

[PATCH bpf-next v8 06/11] bpf,landlock: Add a new map type: inode

2018-02-26 Thread Mickaël Salaün
This new map store arbitrary 64-bits values referenced by inode keys.
The map can be updated from user space with file descriptor pointing to
inodes tied to a file system.  From an eBPF (Landlock) program point of
view, such a map is read-only and can only be used to retrieved a
64-bits value tied to a given inode.  This is useful to recognize an
inode tagged by user space, without access right to this inode (i.e. no
need to have a write access to this inode).

This also add new BPF map object types: landlock_tag_object and
landlock_chain.  The landlock_chain pointer is needed to be able to
handle multiple tags per inode.  The landlock_tag_object is needed to
update a reference to a list of shared tags.  This is typically used by
a struct file (reference) and a struct inode (shared list of tags).
This way, we can account the process/user for the number of tagged
files, while still being able to read the tags from the pointed inode.

Add dedicated BPF functions to handle this type of map:
* bpf_inode_map_update_elem()
* bpf_inode_map_lookup_elem()
* bpf_inode_map_delete_elem()

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
Cc: Jann Horn <j...@thejh.net>
---

Changes since v7:
* new design with a dedicated map and a BPF function to tie a value to
  an inode
* add the ability to set or get a tag on an inode from a Landlock
  program

Changes since v6:
* remove WARN_ON() for missing dentry->d_inode
* refactor bpf_landlock_func_proto() (suggested by Kees Cook)

Changes since v5:
* cosmetic fixes and rebase

Changes since v4:
* use a file abstraction (handle) to wrap inode, dentry, path and file
  structs
* remove bpf_landlock_cmp_fs_beneath()
* rename the BPF helper and move it to kernel/bpf/
* tighten helpers accessible by a Landlock rule

Changes since v3:
* remove bpf_landlock_cmp_fs_prop() (suggested by Alexei Starovoitov)
* add hooks dealing with struct inode and struct path pointers:
  inode_permission and inode_getattr
* add abstraction over eBPF helper arguments thanks to wrapping structs
* add bpf_landlock_get_fs_mode() helper to check file type and mode
* merge WARN_ON() (suggested by Kees Cook)
* fix and update bpf_helpers.h
* use BPF_CALL_* for eBPF helpers (suggested by Alexei Starovoitov)
* make handle arraymap safe (RCU) and remove buggy synchronize_rcu()
* factor out the arraymay walk
* use size_t to index array (suggested by Jann Horn)

Changes since v2:
* add MNT_INTERNAL check to only add file handle from user-visible FS
  (e.g. no anonymous inode)
* replace struct file* with struct path* in map_landlock_handle
* add BPF protos
* fix bpf_landlock_cmp_fs_prop_with_struct_file()
---
 include/linux/bpf.h|  18 ++
 include/linux/bpf_types.h  |   3 +
 include/linux/landlock.h   |  24 +++
 include/uapi/linux/bpf.h   |  22 ++-
 kernel/bpf/Makefile|   3 +
 kernel/bpf/core.c  |   1 +
 kernel/bpf/helpers.c   |  38 +
 kernel/bpf/inodemap.c  | 318 +++
 kernel/bpf/syscall.c   |  27 ++-
 kernel/bpf/verifier.c  |  25 +++
 security/landlock/Makefile |   1 +
 security/landlock/tag.c| 373 +
 security/landlock/tag.h|  36 
 security/landlock/tag_fs.c |  59 +++
 security/landlock/tag_fs.h |  26 +++
 tools/include/uapi/linux/bpf.h |  22 ++-
 16 files changed, 993 insertions(+), 3 deletions(-)
 create mode 100644 kernel/bpf/inodemap.c
 create mode 100644 security/landlock/tag.c
 create mode 100644 security/landlock/tag.h
 create mode 100644 security/landlock/tag_fs.c
 create mode 100644 security/landlock/tag_fs.h

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 377b2f3519f3..c9b940a44c3e 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -127,6 +127,10 @@ enum bpf_arg_type {
 
ARG_PTR_TO_CTX, /* pointer to context */
ARG_ANYTHING,   /* any (initialized) argument is ok */
+
+   ARG_PTR_TO_INODE,   /* pointer to a struct inode */
+   ARG_PTR_TO_LL_TAG_OBJ,  /* pointer to a struct landlock_tag_object */
+   ARG_PTR_TO_LL_CHAIN,/* pointer to a struct landlock_chain */
 };
 
 /* type of values returned from helper functions */
@@ -184,6 +188,9 @@ enum bpf_reg_type {
PTR_TO_PACKET_META,  /* skb->data - meta_len */
PTR_TO_PACKET,   /* reg points to skb->data */
PTR_TO_PACKET_END,   /* skb->data + headlen */
+   PTR_TO_INODE,/* reg points to struct inode */
+   PTR_TO_LL_TAG_OBJ,   /* reg points to struct landlock_tag_object */
+

[PATCH bpf-next v8 01/11] fs,security: Add a security blob to nameidata

2018-02-26 Thread Mickaël Salaün
The function current_nameidata_security(struct inode *) can be used to
retrieve a blob's pointer address tied to the inode being walk through.
This enable to follow a path lookup and know where an inode access come
from. This is needed for the Landlock LSM to be able to restrict access
to file path.

The LSM hook nameidata_free_security(struct inode *) is called before
freeing the associated nameidata.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexander Viro <v...@zeniv.linux.org.uk>
Cc: Casey Schaufler <ca...@schaufler-ca.com>
Cc: James Morris <jmor...@namei.org>
Cc: John Johansen <john.johan...@canonical.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Paul Moore <p...@paul-moore.com>
Cc: "Serge E. Hallyn" <se...@hallyn.com>
Cc: Stephen Smalley <s...@tycho.nsa.gov>
Cc: Tetsuo Handa <penguin-ker...@i-love.sakura.ne.jp>
Cc: linux-fsde...@vger.kernel.org
---
 fs/namei.c| 39 +++
 include/linux/lsm_hooks.h |  7 +++
 include/linux/namei.h | 14 +-
 include/linux/security.h  |  7 +++
 security/security.c   |  7 +++
 5 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/fs/namei.c b/fs/namei.c
index 921ae32dbc80..d592b3fb0d1e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -505,6 +505,9 @@ struct nameidata {
struct inode*link_inode;
unsignedroot_seq;
int dfd;
+#ifdef CONFIG_SECURITY
+   struct nameidata_lookup lookup;
+#endif
 } __randomize_layout;
 
 static void set_nameidata(struct nameidata *p, int dfd, struct filename *name)
@@ -515,6 +518,9 @@ static void set_nameidata(struct nameidata *p, int dfd, 
struct filename *name)
p->name = name;
p->total_link_count = old ? old->total_link_count : 0;
p->saved = old;
+#ifdef CONFIG_SECURITY
+   p->lookup.security = NULL;
+#endif
current->nameidata = p;
 }
 
@@ -522,6 +528,7 @@ static void restore_nameidata(void)
 {
struct nameidata *now = current->nameidata, *old = now->saved;
 
+   security_nameidata_put_lookup(>lookup, now->inode);
current->nameidata = old;
if (old)
old->total_link_count = now->total_link_count;
@@ -549,6 +556,27 @@ static int __nd_alloc_stack(struct nameidata *nd)
return 0;
 }
 
+#ifdef CONFIG_SECURITY
+/**
+ * current_nameidata_lookup - get the state of the current path walk
+ *
+ * @inode: inode associated to the path walk
+ *
+ * Used by LSM modules for access restriction based on path walk. The LSM is in
+ * charge of the lookup->security blob allocation and management. The hook
+ * security_nameidata_put_lookup() will be called after the path walk end.
+ *
+ * Return ERR_PTR(-ENOENT) if there is no match.
+ */
+struct nameidata_lookup *current_nameidata_lookup(const struct inode *inode)
+{
+   if (!current->nameidata || current->nameidata->inode != inode)
+   return ERR_PTR(-ENOENT);
+   return >nameidata->lookup;
+}
+EXPORT_SYMBOL(current_nameidata_lookup);
+#endif
+
 /**
  * path_connected - Verify that a path->dentry is below path->mnt.mnt_root
  * @path: nameidate to verify
@@ -2009,6 +2037,13 @@ static inline u64 hash_name(const void *salt, const char 
*name)
 
 #endif
 
+static inline void refresh_lookup(struct nameidata *nd)
+{
+#ifdef CONFIG_SECURITY
+   nd->lookup.type = nd->last_type;
+#endif
+}
+
 /*
  * Name resolution.
  * This is the basic name resolution function, turning a pathname into
@@ -2025,6 +2060,8 @@ static int link_path_walk(const char *name, struct 
nameidata *nd)
name++;
if (!*name)
return 0;
+   /* be ready for may_lookup() */
+   refresh_lookup(nd);
 
/* At this point we know we have a real path component. */
for(;;) {
@@ -2064,6 +2101,8 @@ static int link_path_walk(const char *name, struct 
nameidata *nd)
nd->last.hash_len = hash_len;
nd->last.name = name;
nd->last_type = type;
+   /* be ready for the next security_inode_permission() */
+   refresh_lookup(nd);
 
name += hashlen_len(hash_len);
if (!*name)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7161d8e7ee79..d71cf183f0be 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -428,6 +428,10 @@
  * security module does not know about attribute or a negative error code
  * to abort the copy up. Note that the caller is responsible for reading
  * and writing the xattrs as this hook is merely a filter.
+ * @nameidata_put_lookup:
+ * Deallocate and clear the current's nameidata->lookup.security field.
+ * @lookup->security contains the security structure to be freed.
+ * @inode is the last associated inode to the path 

[PATCH bpf-next v8 08/11] landlock: Add ptrace restrictions

2018-02-26 Thread Mickaël Salaün
A landlocked process has less privileges than a non-landlocked process
and must then be subject to additional restrictions when manipulating
processes. To be allowed to use ptrace(2) and related syscalls on a
target process, a landlocked process must have a subset of the target
process' rules.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---

Changes since v6:
* factor out ptrace check
* constify pointers
* cleanup headers
* use the new security_add_hooks()
---
 security/landlock/Makefile   |   2 +-
 security/landlock/hooks_ptrace.c | 124 +++
 security/landlock/hooks_ptrace.h |  11 
 security/landlock/init.c |   2 +
 4 files changed, 138 insertions(+), 1 deletion(-)
 create mode 100644 security/landlock/hooks_ptrace.c
 create mode 100644 security/landlock/hooks_ptrace.h

diff --git a/security/landlock/Makefile b/security/landlock/Makefile
index d0f532a93b4e..605504d852d3 100644
--- a/security/landlock/Makefile
+++ b/security/landlock/Makefile
@@ -3,4 +3,4 @@ obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o
 landlock-y := init.o chain.o task.o \
tag.o tag_fs.o \
enforce.o enforce_seccomp.o \
-   hooks.o hooks_cred.o hooks_fs.o
+   hooks.o hooks_cred.o hooks_fs.o hooks_ptrace.o
diff --git a/security/landlock/hooks_ptrace.c b/security/landlock/hooks_ptrace.c
new file mode 100644
index ..f1b977b9c808
--- /dev/null
+++ b/security/landlock/hooks_ptrace.c
@@ -0,0 +1,124 @@
+/*
+ * Landlock LSM - ptrace hooks
+ *
+ * Copyright © 2017 Mickaël Salaün <m...@digikod.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include  /* ARRAY_SIZE */
+#include 
+#include  /* struct task_struct */
+#include 
+
+#include "common.h" /* struct landlock_prog_set */
+#include "hooks.h" /* landlocked() */
+#include "hooks_ptrace.h"
+
+static bool progs_are_subset(const struct landlock_prog_set *parent,
+   const struct landlock_prog_set *child)
+{
+   size_t i;
+
+   if (!parent || !child)
+   return false;
+   if (parent == child)
+   return true;
+
+   for (i = 0; i < ARRAY_SIZE(child->programs); i++) {
+   struct landlock_prog_list *walker;
+   bool found_parent = false;
+
+   if (!parent->programs[i])
+   continue;
+   for (walker = child->programs[i]; walker;
+   walker = walker->prev) {
+   if (walker == parent->programs[i]) {
+   found_parent = true;
+   break;
+   }
+   }
+   if (!found_parent)
+   return false;
+   }
+   return true;
+}
+
+static bool task_has_subset_progs(const struct task_struct *parent,
+   const struct task_struct *child)
+{
+#ifdef CONFIG_SECCOMP_FILTER
+   if (progs_are_subset(parent->seccomp.landlock_prog_set,
+   child->seccomp.landlock_prog_set))
+   /* must be ANDed with other providers (i.e. cgroup) */
+   return true;
+#endif /* CONFIG_SECCOMP_FILTER */
+   return false;
+}
+
+static int task_ptrace(const struct task_struct *parent,
+   const struct task_struct *child)
+{
+   if (!landlocked(parent))
+   return 0;
+
+   if (!landlocked(child))
+   return -EPERM;
+
+   if (task_has_subset_progs(parent, child))
+   return 0;
+
+   return -EPERM;
+}
+
+/**
+ * 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 has Landlock programs, then the child must have at least
+ * the same programs.  Else denied.
+ *
+ * Determine whether a process may access another, returning 0 if permission
+ * granted, -errno if denied.
+ */
+static int hook_ptrace_access_check(struct task_struct *child,
+   unsigned int mode)
+{
+   return task_ptrace(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 has Landlock programs, then the current task must have the
+ * same or more programs.
+ * Else den

[PATCH bpf-next v8 11/11] landlock: Add user and kernel documentation for Landlock

2018-02-26 Thread Mickaël Salaün
This documentation can be built with the Sphinx framework.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Jonathan Corbet <cor...@lwn.net>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---

Changes since v7:
* update documentation according to the Landlock revamp

Changes since v6:
* add a check for ctx->event
* rename BPF_PROG_TYPE_LANDLOCK to BPF_PROG_TYPE_LANDLOCK_RULE
* rename Landlock version to ABI to better reflect its purpose and add a
  dedicated changelog section
* update tables
* relax no_new_privs recommendations
* remove ABILITY_WRITE related functions
* reword rule "appending" to "prepending" and explain it
* cosmetic fixes

Changes since v5:
* update the rule hierarchy inheritance explanation
* briefly explain ctx->arg2
* add ptrace restrictions
* explain EPERM
* update example (subtype)
* use ":manpage:"
---
 Documentation/security/index.rst   |   1 +
 Documentation/security/landlock/index.rst  |  19 +++
 Documentation/security/landlock/kernel.rst | 100 ++
 Documentation/security/landlock/user.rst   | 206 +
 4 files changed, 326 insertions(+)
 create mode 100644 Documentation/security/landlock/index.rst
 create mode 100644 Documentation/security/landlock/kernel.rst
 create mode 100644 Documentation/security/landlock/user.rst

diff --git a/Documentation/security/index.rst b/Documentation/security/index.rst
index 298a94a33f05..1db294025d0f 100644
--- a/Documentation/security/index.rst
+++ b/Documentation/security/index.rst
@@ -11,3 +11,4 @@ Security Documentation
LSM
self-protection
tpm/index
+   landlock/index
diff --git a/Documentation/security/landlock/index.rst 
b/Documentation/security/landlock/index.rst
new file mode 100644
index ..8afde6a5805c
--- /dev/null
+++ b/Documentation/security/landlock/index.rst
@@ -0,0 +1,19 @@
+=
+Landlock LSM: programmatic access control
+=
+
+Landlock is a stackable Linux Security Module (LSM) that makes it possible to
+create security sandboxes.  This kind of sandbox is expected to help mitigate
+the security impact of bugs or unexpected/malicious behaviors in user-space
+applications.  The current version allows only a process with the global
+CAP_SYS_ADMIN capability to create such sandboxes but the ultimate goal of
+Landlock is to empower any process, including unprivileged ones, to securely
+restrict themselves.  Landlock is inspired by seccomp-bpf but instead of
+filtering syscalls and their raw arguments, a Landlock rule can inspect the use
+of kernel objects like files and hence make a decision according to the kernel
+semantic.
+
+.. toctree::
+
+user
+kernel
diff --git a/Documentation/security/landlock/kernel.rst 
b/Documentation/security/landlock/kernel.rst
new file mode 100644
index ..0a52915e346c
--- /dev/null
+++ b/Documentation/security/landlock/kernel.rst
@@ -0,0 +1,100 @@
+==
+Landlock: kernel documentation
+==
+
+eBPF properties
+===
+
+To get an expressive language while still being safe and small, Landlock is
+based on eBPF. Landlock should be usable by untrusted processes and must
+therefore expose a minimal attack surface. The eBPF bytecode is minimal,
+powerful, widely used and designed to be used by untrusted applications. Thus,
+reusing the eBPF support in the kernel enables a generic approach while
+minimizing new code.
+
+An eBPF program has access to an eBPF context containing some fields used to
+inspect the current object. These arguments can be used directly (e.g. cookie)
+or passed to helper functions according to their types (e.g. inode pointer). It
+is then possible to do complex access checks without race conditions or
+inconsistent evaluation (i.e.  `incorrect mirroring of the OS code and state
+<https://www.ndss-symposium.org/ndss2003/traps-and-pitfalls-practical-problems-system-call-interposition-based-security-tools/>`_).
+
+A Landlock hook describes a particular access type.  For now, there is three
+hooks dedicated to filesystem related operations: LANDLOCK_HOOK_FS_PICK,
+LANDLOCK_HOOK_FS_WALK and LANDLOCK_HOOK_FS_GET.  A Landlock program is tied to
+one hook.  This makes it possible to statically check context accesses,
+potentially performed by such program, and hence prevents kernel address leaks
+and ensure the right use of hook arguments with eBPF functions.  Any user can
+add multiple Landlock programs per Landlock hook.  They are stacked and
+evaluated one after the other, starting from the most recent program, as
+seccomp-bpf doe

[PATCH bpf-next v8 10/11] bpf,landlock: Add tests for Landlock

2018-02-26 Thread Mickaël Salaün
Test basic context access, ptrace protection and filesystem hooks and
Landlock program chaining with multiple cases.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
Cc: Shuah Khan <sh...@kernel.org>
Cc: Will Drewry <w...@chromium.org>
---

Changes since v7:
* update tests and add new ones for filesystem hierarchy and Landlock
  chains.

Changes since v6:
* use the new kselftest_harness.h
* use const variables
* replace ASSERT_STEP with ASSERT_*
* rename BPF_PROG_TYPE_LANDLOCK to BPF_PROG_TYPE_LANDLOCK_RULE
* force sample library rebuild
* fix install target

Changes since v5:
* add subtype test
* add ptrace tests
* split and rename files
* cleanup and rebase
---
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/bpf/bpf_helpers.h  |   7 +
 tools/testing/selftests/bpf/test_verifier.c|  84 +
 tools/testing/selftests/landlock/.gitignore|   5 +
 tools/testing/selftests/landlock/Makefile  |  35 ++
 tools/testing/selftests/landlock/test.h|  31 ++
 tools/testing/selftests/landlock/test_base.c   |  27 ++
 tools/testing/selftests/landlock/test_chain.c  | 249 +
 tools/testing/selftests/landlock/test_fs.c | 492 +
 tools/testing/selftests/landlock/test_ptrace.c | 158 
 10 files changed, 1089 insertions(+)
 create mode 100644 tools/testing/selftests/landlock/.gitignore
 create mode 100644 tools/testing/selftests/landlock/Makefile
 create mode 100644 tools/testing/selftests/landlock/test.h
 create mode 100644 tools/testing/selftests/landlock/test_base.c
 create mode 100644 tools/testing/selftests/landlock/test_chain.c
 create mode 100644 tools/testing/selftests/landlock/test_fs.c
 create mode 100644 tools/testing/selftests/landlock/test_ptrace.c

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 7442dfb73b7f..5d00deb3cab6 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -14,6 +14,7 @@ TARGETS += gpio
 TARGETS += intel_pstate
 TARGETS += ipc
 TARGETS += kcmp
+TARGETS += landlock
 TARGETS += lib
 TARGETS += membarrier
 TARGETS += memfd
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h 
b/tools/testing/selftests/bpf/bpf_helpers.h
index dde2c11d7771..414e267491f7 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -86,6 +86,13 @@ static int (*bpf_perf_prog_read_value)(void *ctx, void *buf,
(void *) BPF_FUNC_perf_prog_read_value;
 static int (*bpf_override_return)(void *ctx, unsigned long rc) =
(void *) BPF_FUNC_override_return;
+static unsigned long long (*bpf_inode_map_lookup)(void *map, void *key) =
+   (void *) BPF_FUNC_inode_map_lookup;
+static unsigned long long (*bpf_inode_get_tag)(void *inode, void *chain) =
+   (void *) BPF_FUNC_inode_get_tag;
+static unsigned long long (*bpf_landlock_set_tag)(void *tag_obj, void *chain,
+ unsigned long long value) =
+   (void *) BPF_FUNC_landlock_set_tag;
 
 /* llvm builtin functions that eBPF C program may use to
  * emit BPF_LD_ABS and BPF_LD_IND instructions
diff --git a/tools/testing/selftests/bpf/test_verifier.c 
b/tools/testing/selftests/bpf/test_verifier.c
index 3c24a5a7bafc..5f68b95187fe 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -11240,6 +11241,89 @@ static struct bpf_test tests[] = {
.result = REJECT,
.has_prog_subtype = true,
},
+   {
+   "missing subtype",
+   .insns = {
+   BPF_MOV32_IMM(BPF_REG_0, 0),
+   BPF_EXIT_INSN(),
+   },
+   .errstr = "",
+   .result = REJECT,
+   .prog_type = BPF_PROG_TYPE_LANDLOCK_HOOK,
+   },
+   {
+   "landlock/fs_pick: always accept",
+   .insns = {
+   BPF_MOV32_IMM(BPF_REG_0, 0),
+   BPF_EXIT_INSN(),
+   },
+   .result = ACCEPT,
+   .prog_type = BPF_PROG_TYPE_LANDLOCK_HOOK,
+   .has_prog_subtype = true,
+   .prog_subtype = {
+   .landlock_hook = {
+   .type = LANDLOCK_HOOK_FS_PICK,
+   .triggers = LANDLOCK_TRIGGER_FS_PICK_READ,
+   }
+   },
+   },
+   {
+   "landlock/fs_pick: read 

[PATCH bpf-next v8 07/11] landlock: Handle filesystem access control

2018-02-26 Thread Mickaël Salaün
This add three Landlock: FS_WALK, FS_PICK and FS_GET.

The FS_WALK hook is used to walk through a file path. A program tied to
this hook will be evaluated for each directory traversal except the last
one if it is the leaf of the path.

The FS_PICK hook is used to validate a set of actions requested on a
file. This actions are defined with triggers (e.g. read, write, open,
append...).

The FS_GET hook is used to tag open files, which is necessary to be able
to evaluate relative paths.  A program tied to this hook can tag a file
with an inode map.

A Landlock program can be chained to another if it is permitted by the
BPF verifier. A FS_WALK can be chained to a FS_PICK which can be chained
to a FS_GET.

The Landlock LSM hook registration is done after other LSM to only run
actions from user-space, via eBPF programs, if the access was granted by
major (privileged) LSMs.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---

Changes since v7:
* major rewrite with clean Landlock hooks able to deal with file paths

Changes since v6:
* add 3 more sub-events: IOCTL, LOCK, FCNTL
  https://lkml.kernel.org/r/2fbc99a6-f190-f335-bd14-04bdeed35...@digikod.net
* use the new security_add_hooks()
* explain the -Werror=unused-function
* constify pointers
* cleanup headers

Changes since v5:
* split hooks.[ch] into hooks.[ch] and hooks_fs.[ch]
* add more documentation
* cosmetic fixes
* rebase (SCALAR_VALUE)

Changes since v4:
* add LSM hook abstraction called Landlock event
  * use the compiler type checking to verify hooks use by an event
  * handle all filesystem related LSM hooks (e.g. file_permission,
mmap_file, sb_mount...)
* register BPF programs for Landlock just after LSM hooks registration
* move hooks registration after other LSMs
* add failsafes to check if a hook is not used by the kernel
* allow partial raw value access form the context (needed for programs
  generated by LLVM)

Changes since v3:
* split commit
* add hooks dealing with struct inode and struct path pointers:
  inode_permission and inode_getattr
* add abstraction over eBPF helper arguments thanks to wrapping structs
---
 include/linux/lsm_hooks.h   |5 +
 security/landlock/Makefile  |5 +-
 security/landlock/common.h  |9 +
 security/landlock/enforce_seccomp.c |   10 +
 security/landlock/hooks.c   |  121 +
 security/landlock/hooks.h   |   35 ++
 security/landlock/hooks_cred.c  |   52 ++
 security/landlock/hooks_cred.h  |1 +
 security/landlock/hooks_fs.c| 1021 +++
 security/landlock/hooks_fs.h|   60 ++
 security/landlock/init.c|   56 ++
 security/landlock/task.c|   34 ++
 security/landlock/task.h|   29 +
 security/security.c |   12 +-
 14 files changed, 1447 insertions(+), 3 deletions(-)
 create mode 100644 security/landlock/hooks.c
 create mode 100644 security/landlock/hooks.h
 create mode 100644 security/landlock/hooks_cred.c
 create mode 100644 security/landlock/hooks_cred.h
 create mode 100644 security/landlock/hooks_fs.c
 create mode 100644 security/landlock/hooks_fs.h
 create mode 100644 security/landlock/task.c
 create mode 100644 security/landlock/task.h

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index d71cf183f0be..c40163385b68 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2032,5 +2032,10 @@ void __init loadpin_add_hooks(void);
 #else
 static inline void loadpin_add_hooks(void) { };
 #endif
+#ifdef CONFIG_SECURITY_LANDLOCK
+extern void __init landlock_add_hooks(void);
+#else
+static inline void __init landlock_add_hooks(void) { }
+#endif /* CONFIG_SECURITY_LANDLOCK */
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/security/landlock/Makefile b/security/landlock/Makefile
index 0e1dd4612ecc..d0f532a93b4e 100644
--- a/security/landlock/Makefile
+++ b/security/landlock/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o
 
-landlock-y := init.o chain.o \
+landlock-y := init.o chain.o task.o \
tag.o tag_fs.o \
-   enforce.o enforce_seccomp.o
+   enforce.o enforce_seccomp.o \
+   hooks.o hooks_cred.o hooks_fs.o
diff --git a/security/landlock/common.h b/security/landlock/common.h
index 245e4ccafcf2..6d36b70068d5 100644
--- a/security/landlock/common.h
+++ b/security/landlock/common.h
@@ -82,4 +82,13 @@ static inline enum landlock_hook_type get_type(struct 
bpf_prog *prog)
return prog->aux->extra->subtype.landlock_hook.type;
 }
 
+__maybe_unused
+static bool current_has_prog_type(enum landlock_hook_type hook_type)
+{
+   struct 

[PATCH bpf-next v8 09/11] bpf: Add a Landlock sandbox example

2018-02-26 Thread Mickaël Salaün
Add a basic sandbox tool to launch a command which is only allowed to
access in a read only or read-write way a whitelist of file hierarchies.

Add to the bpf_load library the ability to handle a BPF program subtype.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---

Changes since v7:
* rewrite the example using an inode map
* add to bpf_load the ability to handle subtypes per program type

Changes since v6:
* check return value of load_and_attach()
* allow to write on pipes
* rename BPF_PROG_TYPE_LANDLOCK to BPF_PROG_TYPE_LANDLOCK_RULE
* rename Landlock version to ABI to better reflect its purpose
* use const variable (suggested by Kees Cook)
* remove useless definitions (suggested by Kees Cook)
* add detailed explanations (suggested by Kees Cook)

Changes since v5:
* cosmetic fixes
* rebase

Changes since v4:
* write Landlock rule in C and compiled it with LLVM
* remove cgroup handling
* remove path handling: only handle a read-only environment
* remove errno return codes

Changes since v3:
* remove seccomp and origin field: completely free from seccomp programs
* handle more FS-related hooks
* handle inode hooks and directory traversal
* add faked but consistent view thanks to ENOENT
* add /lib64 in the example
* fix spelling
* rename some types and definitions (e.g. SECCOMP_ADD_LANDLOCK_RULE)

Changes since v2:
* use BPF_PROG_ATTACH for cgroup handling
---
 samples/bpf/Makefile |   4 +
 samples/bpf/bpf_load.c   |  82 -
 samples/bpf/bpf_load.h   |   7 ++
 samples/bpf/landlock1.h  |  14 
 samples/bpf/landlock1_kern.c | 171 +++
 samples/bpf/landlock1_user.c | 164 +
 6 files changed, 439 insertions(+), 3 deletions(-)
 create mode 100644 samples/bpf/landlock1.h
 create mode 100644 samples/bpf/landlock1_kern.c
 create mode 100644 samples/bpf/landlock1_user.c

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index ec3fc8d88e87..015b1375daa5 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -43,6 +43,7 @@ hostprogs-y += xdp_redirect_cpu
 hostprogs-y += xdp_monitor
 hostprogs-y += xdp_rxq_info
 hostprogs-y += syscall_tp
+hostprogs-y += landlock1
 
 # Libbpf dependencies
 LIBBPF := ../../tools/lib/bpf/bpf.o ../../tools/lib/bpf/nlattr.o
@@ -93,6 +94,7 @@ xdp_redirect_cpu-objs := bpf_load.o $(LIBBPF) 
xdp_redirect_cpu_user.o
 xdp_monitor-objs := bpf_load.o $(LIBBPF) xdp_monitor_user.o
 xdp_rxq_info-objs := bpf_load.o $(LIBBPF) xdp_rxq_info_user.o
 syscall_tp-objs := bpf_load.o $(LIBBPF) syscall_tp_user.o
+landlock1-objs := bpf_load.o $(LIBBPF) landlock1_user.o
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
@@ -144,6 +146,7 @@ always += xdp_monitor_kern.o
 always += xdp_rxq_info_kern.o
 always += xdp2skb_meta_kern.o
 always += syscall_tp_kern.o
+always += landlock1_kern.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 HOSTCFLAGS += -I$(srctree)/tools/lib/
@@ -188,6 +191,7 @@ HOSTLOADLIBES_xdp_redirect_cpu += -lelf
 HOSTLOADLIBES_xdp_monitor += -lelf
 HOSTLOADLIBES_xdp_rxq_info += -lelf
 HOSTLOADLIBES_syscall_tp += -lelf
+HOSTLOADLIBES_landlock1 += -lelf
 
 # Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on 
cmdline:
 #  make samples/bpf/ LLC=~/git/llvm/build/bin/llc 
CLANG=~/git/llvm/build/bin/clang
diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index 5bb37db6054b..f7c91093b2f5 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -43,6 +44,9 @@ int prog_array_fd = -1;
 struct bpf_map_data map_data[MAX_MAPS];
 int map_data_count = 0;
 
+struct bpf_subtype_data subtype_data[MAX_PROGS];
+int subtype_data_count = 0;
+
 static int populate_prog_array(const char *event, int prog_fd)
 {
int ind = atoi(event), err;
@@ -67,12 +71,14 @@ static int load_and_attach(const char *event, struct 
bpf_insn *prog, int size)
bool is_cgroup_sk = strncmp(event, "cgroup/sock", 11) == 0;
bool is_sockops = strncmp(event, "sockops", 7) == 0;
bool is_sk_skb = strncmp(event, "sk_skb", 6) == 0;
+   bool is_landlock = strncmp(event, "landlock", 8) == 0;
size_t insns_cnt = size / sizeof(struct bpf_insn);
enum bpf_prog_type prog_type;
char buf[256];
int fd, efd, err, id;
struct perf_event_attr attr = {};
union bpf_prog_subtype *st = NULL;
+   struct bpf_subtype_data *sd = NULL;
 
attr.type = PERF_TYPE_TRACEPOINT;
attr.sample_type = PERF_SAMPLE_RAW;
@@ -97,6 +

Re: [PATCH net-next 0/3] eBPF Seccomp filters

2018-02-13 Thread Mickaël Salaün
seccomp-bpf does not use cBPF but a subset of it. The reason is that it
is meant to reduce the attack surface of the kernel. By limiting the
number of instructions allowed by seccomp-bpf, it really reduce the
possibilities for an attacker to use seccomp-bpf as an entry point to
attack the kernel. Moreover, this subset of cBPF is just fine to filter
simple things as syscall numbers and arguments. Additional return codes
may be added to extend seccomp features.

FYI, I'm tweaking a new version of Landlock, which is not an extension
of seccomp-bpf (as it was at first) but a standalone LSM leveraging eBPF
to create security sandboxes (what seccomp-bpf does not do). I'll send
this version soon but you can get a sneak peek here (the documentation
will come with the final version):
https://github.com/landlock-lsm/linux/commit/6c9131a5ccdf7aa59b23f3a9ae2b73008f41
(please, do not comment this code now)

I think the current seccomp-bpf bytecode is excellent for what it is
meant to do. Landlock leverage eBPF to tackle a more complex problem
(e.g. control access to files, and much more). It is not a seccomp
replacement but a complementary layer of security.

About the verbosity of seccomp filters, you may want to try other ways
to write policies (e.g. https://github.com/google/kafel/ or
https://android.googlesource.com/platform/external/minijail/+/master/tools/generate_seccomp_policy.py
or https://github.com/servo/gaol/blob/master/platform/linux/seccomp.rs).

Regards,
 Mickaël

On 13/02/2018 16:42, Sargun Dhillon wrote:
> This patchset enables seccomp filters to be written in eBPF. Although,
> this patchset doesn't introduce much of the functionality enabled by
> eBPF, it lays the ground work for it.
> 
> It also introduces the capability to dump eBPF filters via the PTRACE
> API in order to make it so that CHECKPOINT_RESTORE will be satisifed.
> In the attached samples, there's an example of this. One can then use
> BPF_OBJ_GET_INFO_BY_FD in order to get the actual code of the program,
> and use that at reload time.
> 
> The primary reason for not adding maps support in this patchset is
> to avoid introducing new complexities around PR_SET_NO_NEW_PRIVS.
> If we have a map that the BPF program can read, it can potentially
> "change" privileges after running. It seems like doing writes only
> is safe, because it can be pure, and side effect free, and therefore
> not negatively effect PR_SET_NO_NEW_PRIVS. Nonetheless, if we come
> to an agreement, this can be in a follow-up patchset.
> 
> 
> Sargun Dhillon (3):
>   bpf, seccomp: Add eBPF filter capabilities
>   seccomp, ptrace: Add a mechanism to retrieve attached eBPF seccomp
> filters
>   bpf: Add eBPF seccomp sample programs
> 
>  arch/Kconfig |   7 ++
>  include/linux/bpf_types.h|   3 +
>  include/linux/seccomp.h  |  12 +++
>  include/uapi/linux/bpf.h |   2 +
>  include/uapi/linux/ptrace.h  |   5 +-
>  include/uapi/linux/seccomp.h |  15 ++--
>  kernel/bpf/syscall.c |   1 +
>  kernel/ptrace.c  |   3 +
>  kernel/seccomp.c | 185 
> ++-
>  samples/bpf/Makefile |   9 +++
>  samples/bpf/bpf_load.c   |   9 ++-
>  samples/bpf/seccomp1_kern.c  |  17 
>  samples/bpf/seccomp1_user.c  |  34 
>  samples/bpf/seccomp2_kern.c  |  24 ++
>  samples/bpf/seccomp2_user.c  |  66 +++
>  15 files changed, 362 insertions(+), 30 deletions(-)
>  create mode 100644 samples/bpf/seccomp1_kern.c
>  create mode 100644 samples/bpf/seccomp1_user.c
>  create mode 100644 samples/bpf/seccomp2_kern.c
>  create mode 100644 samples/bpf/seccomp2_user.c
> 



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v1] samples/bpf: Partially fixes the bpf.o build

2018-01-26 Thread Mickaël Salaün

On 26/01/2018 03:16, Alexei Starovoitov wrote:
> On Fri, Jan 26, 2018 at 01:39:30AM +0100, Mickaël Salaün wrote:
>> Do not build lib/bpf/bpf.o with this Makefile but use the one from the
>> library directory.  This avoid making a buggy bpf.o file (e.g. missing
>> symbols).
> 
> could you provide an example?
> What symbols will be missing?
> I don't think there is an issue with existing Makefile.

You can run this commands:
make -C samples/bpf; nm tools/lib/bpf/bpf.o > a; make -C tools/lib/bpf;
nm tools/lib/bpf/bpf.o > b; diff -u a b

Symbols like bzero and sys_bpf are missing with the samples/bpf
Makefile, which makes the bpf.o shrink from 25K to 7K.

> 
>> This patch is useful if some code (e.g. Landlock tests) needs both the
>> bpf.o (from tools/lib/bpf) and the bpf_load.o (from samples/bpf).
> 
> is that some future patches?

Yes, I'll send them next week.

> 
> we're trying to move everything form samples/bpf/ into selftests/bpf/
> and convert to use libbpf.a instead of obsolete bpf_load.c
> Please use this approach for landlock as well.

Ok, it should be better with this lib.

> 
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>> Cc: Alexei Starovoitov <a...@kernel.org>
>> Cc: Daniel Borkmann <dan...@iogearbox.net>
>> ---
>>
>> This is not a complet fix because the call to multi_depend with
>> $(host-cmulti) from scripts/Makefile.host force the build of bpf.o
>> anyway. I'm not sure how to completely avoid this automatic build
>> though.
>> ---
>>  samples/bpf/Makefile | 5 -
>>  1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
>> index 7f61a3d57fa7..64335bb94f9f 100644
>> --- a/samples/bpf/Makefile
>> +++ b/samples/bpf/Makefile
>> @@ -201,13 +201,16 @@ CLANG_ARCH_ARGS = -target $(ARCH)
>>  endif
>>  
>>  # Trick to allow make to be run from this directory
>> -all:
>> +all: $(LIBBPF)
>>  $(MAKE) -C ../../ $(CURDIR)/
>>  
>>  clean:
>>  $(MAKE) -C ../../ M=$(CURDIR) clean
>>  @rm -f *~
>>  
>> +$(LIBBPF): FORCE
>> +$(MAKE) -C $(dir $@) $(notdir $@)
>> +
>>  $(obj)/syscall_nrs.s:   $(src)/syscall_nrs.c
>>  $(call if_changed_dep,cc_s_c)
>>  
>> -- 
>> 2.15.1
>>
> 



signature.asc
Description: OpenPGP digital signature


[PATCH net-next v1] samples/bpf: Partially fixes the bpf.o build

2018-01-25 Thread Mickaël Salaün
Do not build lib/bpf/bpf.o with this Makefile but use the one from the
library directory.  This avoid making a buggy bpf.o file (e.g. missing
symbols).

This patch is useful if some code (e.g. Landlock tests) needs both the
bpf.o (from tools/lib/bpf) and the bpf_load.o (from samples/bpf).

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Daniel Borkmann <dan...@iogearbox.net>
---

This is not a complet fix because the call to multi_depend with
$(host-cmulti) from scripts/Makefile.host force the build of bpf.o
anyway. I'm not sure how to completely avoid this automatic build
though.
---
 samples/bpf/Makefile | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 7f61a3d57fa7..64335bb94f9f 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -201,13 +201,16 @@ CLANG_ARCH_ARGS = -target $(ARCH)
 endif
 
 # Trick to allow make to be run from this directory
-all:
+all: $(LIBBPF)
$(MAKE) -C ../../ $(CURDIR)/
 
 clean:
$(MAKE) -C ../../ M=$(CURDIR) clean
@rm -f *~
 
+$(LIBBPF): FORCE
+   $(MAKE) -C $(dir $@) $(notdir $@)
+
 $(obj)/syscall_nrs.s:  $(src)/syscall_nrs.c
$(call if_changed_dep,cc_s_c)
 
-- 
2.15.1



[PATCH net-next v1] bpf: Use the IS_FD_ARRAY() macro in map_update_elem()

2018-01-25 Thread Mickaël Salaün
Make the code more readable.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Daniel Borkmann <dan...@iogearbox.net>
---
 kernel/bpf/syscall.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 5bdb0cc84ad2..e24aa3241387 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -709,10 +709,7 @@ static int map_update_elem(union bpf_attr *attr)
err = bpf_percpu_hash_update(map, key, value, attr->flags);
} else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) {
err = bpf_percpu_array_update(map, key, value, attr->flags);
-   } else if (map->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY ||
-  map->map_type == BPF_MAP_TYPE_PROG_ARRAY ||
-  map->map_type == BPF_MAP_TYPE_CGROUP_ARRAY ||
-  map->map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS) {
+   } else if (IS_FD_ARRAY(map)) {
rcu_read_lock();
err = bpf_fd_array_map_update_elem(map, f.file, key, value,
   attr->flags);
-- 
2.15.1



Re: RFC(v2): Audit Kernel Container IDs

2017-12-09 Thread Mickaël Salaün

On 12/10/2017 18:33, Casey Schaufler wrote:
> On 10/12/2017 7:14 AM, Richard Guy Briggs wrote:
>> Containers are a userspace concept.  The kernel knows nothing of them.
>>
>> The Linux audit system needs a way to be able to track the container
>> provenance of events and actions.  Audit needs the kernel's help to do
>> this.
>>
>> Since the concept of a container is entirely a userspace concept, a
>> registration from the userspace container orchestration system initiates
>> this.  This will define a point in time and a set of resources
>> associated with a particular container with an audit container ID.
>>
>> The registration is a pseudo filesystem (proc, since PID tree already
>> exists) write of a u8[16] UUID representing the container ID to a file
>> representing a process that will become the first process in a new
>> container.  This write might place restrictions on mount namespaces
>> required to define a container, or at least careful checking of
>> namespaces in the kernel to verify permissions of the orchestrator so it
>> can't change its own container ID.  A bind mount of nsfs may be
>> necessary in the container orchestrator's mntNS.
>> Note: Use a 128-bit scalar rather than a string to make compares faster
>> and simpler.
>>
>> Require a new CAP_CONTAINER_ADMIN to be able to carry out the
>> registration.
> 
> Hang on. If containers are a user space concept, how can
> you want CAP_CONTAINER_ANYTHING? If there's not such thing as
> a container, how can you be asking for a capability to manage
> them?
> 
>>   At that time, record the target container's user-supplied
>> container identifier along with the target container's first process
>> (which may become the target container's "init" process) process ID
>> (referenced from the initial PID namespace), all namespace IDs (in the
>> form of a nsfs device number and inode number tuple) in a new auxilliary
>> record AUDIT_CONTAINER with a qualifying op=$action field.

Here is an idea to avoid privilege problems or the need for a new
capability: make it automatic. What makes a container a container seems
to be the use of at least a namespace. What about automatically create
and assign an ID to a process when it enters a namespace different than
one of its parent process? This delegates the (permission)
responsibility to the use of namespaces (e.g. /proc/sys/user/max_* limit).

One interesting side effect of this approach would be to be able to
identify which processes are in the same set of namespaces, even if not
spawn from the container but entered after its creation (i.e. using
setns), by creating container IDs as a (deterministic) checksum from the
/proc/self/ns/* IDs.

Since the concern is to identify a container, I think the ability to
audit the switch from one container ID to another is enough. I don't
think we need nested IDs.

As a side note, you may want to take a look at the Linux-VServer's XID.

Regards,
 Mickaël



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v7 08/10] bpf: Add a Landlock sandbox example

2017-09-02 Thread Mickaël Salaün

On 01/09/2017 12:25, Alban Crequy wrote:
> Hi Mickaël,
> 
> On 21 August 2017 at 02:09, Mickaël Salaün <m...@digikod.net> wrote:
>> Add a basic sandbox tool to create a process isolated from some part of
>> the system. This sandbox create a read-only environment. It is only
>> allowed to write to a character device such as a TTY:
> ...
>> +   /*
>> +* This check allows the action on the file if it is a directory or a
>> +* pipe. Otherwise, a message is printed to the eBPF log.
>> +*/
>> +   if (S_ISCHR(ret) || S_ISFIFO(ret))
>> +   return 0;
> 
> 
> The comment says "directory", but the code checks for "character device".
> 
> Thanks!
> Alban
> 

Fixed, thanks!



signature.asc
Description: OpenPGP digital signature


Re: Permissions for eBPF objects

2017-08-29 Thread Mickaël Salaün

On 29/08/2017 03:44, Chenbo Feng wrote:
> On Mon, Aug 28, 2017 at 6:15 PM, Alexei Starovoitov
>  wrote:
>> On Mon, Aug 28, 2017 at 05:47:19PM -0700, Chenbo Feng wrote:
>>> On Fri, Aug 25, 2017 at 6:03 PM, Alexei Starovoitov
>>>  wrote:
 On Fri, Aug 25, 2017 at 10:07:27PM +0200, Daniel Borkmann wrote:
> On 08/25/2017 09:52 PM, Chenbo Feng wrote:
>> On Fri, Aug 25, 2017 at 12:45 PM, Jeffrey Vander Stoep 
>>  wrote:
>>> On Fri, Aug 25, 2017 at 12:26 PM, Stephen Smalley  
>>> wrote:
 On Fri, 2017-08-25 at 11:01 -0700, Jeffrey Vander Stoep via Selinux
 wrote:
> I’d like to get your thoughts on adding LSM permission checks on BPF
> objects.

 before reinventing the wheel please take a look at landlock work.
 Everything that was discussed in this thread is covered by it.
 The patches have been in development for more than a year and most of the 
 early
 issues have been resolved.
 It will be presented again during security summit in LA in September.

>>> I am not very familiar with landlock lsm, isn't this module also
>>> depend on the lsm hooks to do
>>> the landlock check? If so then adding lsm hooks for eBPF object seems
>>> not conflict with the
>>> work on progress.
>>
>> I see. I got it the other way around. What lsm checks are you proposing?
>> and why unprivileged_bpf_disabled is not enough?
>> you want to allow unpriv only for specific user(s) ?
>>
> Exactly, the proposal patch I am currently working on will add checks
> before map creation,
> map read,  and map modify, since all these functionalities will be
> available to all users when
> unprivileged_bpf_disabled is turned off. And eBPF prog_load may also
> need a check as well
> since loading some types of program is not restricted either.
> 

It would be interesting to be able to check a wide range of actions
performed with the BPF syscall: the command and the union bpf_attr
argument. Because it is a multiplexer, that may be challenging, though.



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v7 05/10] landlock: Add LSM hooks related to filesystem

2017-08-27 Thread Mickaël Salaün

On 26/08/2017 03:16, Alexei Starovoitov wrote:
> On Fri, Aug 25, 2017 at 10:16:39AM +0200, Mickaël Salaün wrote:

>>>
>>>> +/* a directory inode contains only one dentry */
>>>> +HOOK_NEW_FS(inode_create, 3,
>>>> +  struct inode *, dir,
>>>> +  struct dentry *, dentry,
>>>> +  umode_t, mode,
>>>> +  WRAP_ARG_INODE, dir,
>>>> +  WRAP_ARG_RAW, LANDLOCK_ACTION_FS_WRITE
>>>> +);
>>>
>>> more general question: why you're not wrapping all useful
>>> arguments? Like in the above dentry can be acted upon
>>> by the landlock rule and it's readily available...
>>
>> The context used for the FS event must have the exact same types for all
>> calls. This event is meant to be generic but we can add more specific
>> ones if needed, like I do with FS_IOCTL.
> 
> I see. So all FS events will have dentry as first argument
> regardless of how it is in LSM hook ?

All FS events will have a const struct bpf_handle_fs pointer as first
argument, which wrap either a struct file, a struct dentry, a struct
path or a struct inode. Having only one type (struct bpf_handle_fs) is
needed for the eBPF type checker to verify if a Landlock rule (tied to
an event) can access a context field and which operation is allowed
(with this pointer).

> I guess that will simplify the rules indeed.
> I suspect you're doing it to simplify the LSM->landlock shim layer as well, 
> right?

That's right. This ABI is independent from the LSM API and much more
simpler to use.

> 
>> The idea is to enable people to write simple rules, while being able to
>> write fine grain rules for special cases (e.g. IOCTL) if needed.
>>
>>>
>>> The limitation of only 2 args looks odd.
>>> Is it a hard limitation ? how hard to extend?
>>
>> It's not a hard limit at all. Actually, the FS_FNCTL event should have
>> three arguments (I'll add them in the next series): FS handle, FCNTL
>> command and FCNTL argument. I made sure that it's really easy to add
>> more arguments to the context of an event.
> 
> The reason I'm asking, because I'm not completely convinced that
> adding another argument to existing event will be backwards compatible.
> It looks like you're expecting only two args for all FS events, right?

There is four events right now: FS, FS_IOCTL, FS_LOCK and FS_FCNTL. Each
of them are independent. Their context fields can be of the same or
different eBPF type (e.g. scalar, file handle) and numbers. Actually,
these four events have the same arg1 field (file handle) and the same
arg2 eBPF type (scalar), even if arg2 does not have the same semantic
(i.e. abstract FS action, IOCTL command…).

For example, if we want to extend the FS_FCNTL's context in the future,
we will just have to add an arg3. The check is performed in
landlock_is_valid_access() and landlock_decide(). If a field is not used
by an event, then this field will have a NOT_INIT type and accessing it
will be denied.

> How can you add 3rd argument? All FS events would have to get it,
> but in some LSM hooks such argument will be meaningless, whereas
> in other places it will carry useful info that rule can operate on.
> Would that mean that we'll have FS_3 event type and only few LSM
> hooks will be converted to it. That works, but then we'll lose
> compatiblity with old rules written for FS event and that given hook.
> Otherwise we'd need to have fancy logic to accept old FS event
> into FS_3 LSM hook.

If we want to add a third argument to the FS event, then it will become
accessible because its type will be different than NOT_INIT. This keep
the compatibility with old rules because this new field was then denied.

If we want to add a new argument but only for a subset of the hooks used
by the FS event, then we need to create a new event, like FS_FCNTL. For
example, we may want to add a FS_RENAME event to be able to tie the
source file and the destination file of a rename call.

Anyway, I added the subtype/ABI version as a safeguard in case of
unexpected future evolution.



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v7 08/10] bpf: Add a Landlock sandbox example

2017-08-25 Thread Mickaël Salaün


On 24/08/2017 04:59, Alexei Starovoitov wrote:
> On Mon, Aug 21, 2017 at 02:09:31AM +0200, Mickaël Salaün wrote:
>> Add a basic sandbox tool to create a process isolated from some part of
>> the system. This sandbox create a read-only environment. It is only
>> allowed to write to a character device such as a TTY:
>>
>>   # :> X
>>   # echo $?
>>   0
>>   # ./samples/bpf/landlock1 /bin/sh -i
>>   Launching a new sandboxed process.
>>   # :> Y
>>   cannot create Y: Operation not permitted
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
> 
> ...
> 
>> +SEC("landlock1")
>> +static int landlock_fs_prog1(struct landlock_context *ctx)
>> +{
>> +char fmt_error_mode[] = "landlock1: error: get_mode:%lld\n";
>> +char fmt_error_access[] = "landlock1: error: access denied\n";
>> +long long ret;
>> +
>> +/*
>> + * The argument ctx->arg2 contains bitflags of actions for which the
>> + * rule is run.  The flag LANDLOCK_ACTION_FS_WRITE means that a write
>> + * is requested by one of the userspace processes restricted by this
>> + * rule. The following test allows any actions which does not include a
>> + * write.
>> + */
>> +if (!(ctx->arg2 & LANDLOCK_ACTION_FS_WRITE))
>> +return 0;
>> +
>> +/*
>> + * The argument ctx->arg1 is a file handle for which the process want
>> + * to access. The function bpf_handle_fs_get_mode() return the mode of
>> + * a file (e.g. S_IFBLK, S_IFDIR, S_IFREG...). If there is an error,
>> + * for example if the argument is not a file handle, then an
>> + * -errno value is returned. Otherwise the caller get the file mode as
>> + *  with stat(2).
>> + */
>> +ret = bpf_handle_fs_get_mode((void *)ctx->arg1);
>> +if (ret < 0) {
>> +
>> +/*
>> + * The bpf_trace_printk() function enable to write in the
>> + * kernel eBPF debug log, accessible through
>> + * /sys/kernel/debug/tracing/trace_pipe . To be allowed to call
>> + * this function, a Landlock rule must have the
>> + * LANDLOCK_SUBTYPE_ABILITY_DEBUG ability, which is only
>> + * allowed for CAP_SYS_ADMIN.
>> + */
>> +bpf_trace_printk(fmt_error_mode, sizeof(fmt_error_mode), ret);
>> +return 1;
>> +}
>> +
>> +/*
>> + * This check allows the action on the file if it is a directory or a
>> + * pipe. Otherwise, a message is printed to the eBPF log.
>> + */
>> +if (S_ISCHR(ret) || S_ISFIFO(ret))
>> +return 0;
>> +bpf_trace_printk(fmt_error_access, sizeof(fmt_error_access));
>> +return 1;
>> +}
>> +
>> +/*
>> + * This subtype enable to set the ABI, which ensure that the eBPF context 
>> and
>> + * program behavior will be compatible with this Landlock rule.
>> + */
>> +SEC("subtype")
>> +static const union bpf_prog_subtype _subtype = {
>> +.landlock_rule = {
>> +.abi = 1,
>> +.event = LANDLOCK_SUBTYPE_EVENT_FS,
>> +.ability = LANDLOCK_SUBTYPE_ABILITY_DEBUG,
>> +}
>> +};
> 
> from rule writer perspective can you somehow merge subtype definition
> with the program? It seems they go hand in hand.
> Like section name of the program can be:
> SEC("landlock_rule1/event=fs/ability=debug")
> static int landlock_fs_prog1(struct landlock_context *ctx)...
> and the loader can parse this string and prepare appropriate
> data structures for the kernel.

Right, I'll try that.



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v7 05/10] landlock: Add LSM hooks related to filesystem

2017-08-25 Thread Mickaël Salaün

On 24/08/2017 04:50, Alexei Starovoitov wrote:
> On Mon, Aug 21, 2017 at 02:09:28AM +0200, Mickaël Salaün wrote:
>> Handle 33 filesystem-related LSM hooks for the Landlock filesystem
>> event: LANDLOCK_SUBTYPE_EVENT_FS.
>>
>> A Landlock event wrap LSM hooks for similar kernel object types (e.g.
>> struct file, struct path...). Multiple LSM hooks can trigger the same
>> Landlock event.
>>
>> Landlock handle nine coarse-grained actions: read, write, execute, new,
>> get, remove, ioctl, lock and fcntl. Each of them abstract LSM hook
>> access control in a way that can be extended in the future.
>>
>> The Landlock LSM hook registration is done after other LSM to only run
>> actions from user-space, via eBPF programs, if the access was granted by
>> major (privileged) LSMs.
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
> 
> ...
> 
>> +/* WRAP_ARG_SB */
>> +#define WRAP_ARG_SB_TYPEWRAP_TYPE_FS
>> +#define WRAP_ARG_SB_DEC(arg)\
>> +EXPAND_C(WRAP_TYPE_FS) wrap_##arg = \
>> +{ .type = BPF_HANDLE_FS_TYPE_DENTRY, .dentry = arg->s_root };
>> +#define WRAP_ARG_SB_VAL(arg)((uintptr_t)_##arg)
>> +#define WRAP_ARG_SB_OK(arg) (arg && arg->s_root)
> ...
> 
>> +HOOK_NEW_FS(sb_remount, 2,
>> +struct super_block *, sb,
>> +void *, data,
>> +WRAP_ARG_SB, sb,
>> +WRAP_ARG_RAW, LANDLOCK_ACTION_FS_WRITE
>> +);
> 
> this looks wrong. casting super_block to dentry?

This is called when remounting a block device. The WRAP_ARG_SB take the
sb->s_root as a dentry, it is not a cast. What do you expect from this hook?

> 
>> +/* a directory inode contains only one dentry */
>> +HOOK_NEW_FS(inode_create, 3,
>> +struct inode *, dir,
>> +struct dentry *, dentry,
>> +umode_t, mode,
>> +WRAP_ARG_INODE, dir,
>> +WRAP_ARG_RAW, LANDLOCK_ACTION_FS_WRITE
>> +);
> 
> more general question: why you're not wrapping all useful
> arguments? Like in the above dentry can be acted upon
> by the landlock rule and it's readily available...

The context used for the FS event must have the exact same types for all
calls. This event is meant to be generic but we can add more specific
ones if needed, like I do with FS_IOCTL.

The idea is to enable people to write simple rules, while being able to
write fine grain rules for special cases (e.g. IOCTL) if needed.

> 
> The limitation of only 2 args looks odd.
> Is it a hard limitation ? how hard to extend?

It's not a hard limit at all. Actually, the FS_FNCTL event should have
three arguments (I'll add them in the next series): FS handle, FCNTL
command and FCNTL argument. I made sure that it's really easy to add
more arguments to the context of an event.



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v7 03/10] bpf,landlock: Define an eBPF program type for a Landlock rule

2017-08-25 Thread Mickaël Salaün


On 24/08/2017 04:28, Alexei Starovoitov wrote:
> On Mon, Aug 21, 2017 at 02:09:26AM +0200, Mickaël Salaün wrote:
>> Add a new type of eBPF program used by Landlock rules.
>>
>> This new BPF program type will be registered with the Landlock LSM
>> initialization.
>>
>> Add an initial Landlock Kconfig.
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>> Cc: Alexei Starovoitov <a...@kernel.org>
>> Cc: Andy Lutomirski <l...@amacapital.net>
>> Cc: Daniel Borkmann <dan...@iogearbox.net>
>> Cc: David S. Miller <da...@davemloft.net>
>> Cc: James Morris <james.l.mor...@oracle.com>
>> Cc: Kees Cook <keesc...@chromium.org>
>> Cc: Serge E. Hallyn <se...@hallyn.com>
>> ---
>>
>> Changes since v6:
>> * add 3 more sub-events: IOCTL, LOCK, FCNTL
>>   https://lkml.kernel.org/r/2fbc99a6-f190-f335-bd14-04bdeed35...@digikod.net
>> * rename LANDLOCK_VERSION to LANDLOCK_ABI to better reflect its purpose,
>>   and move it from landlock.h to common.h
>> * rename BPF_PROG_TYPE_LANDLOCK to BPF_PROG_TYPE_LANDLOCK_RULE: an eBPF
>>   program could be used for something else than a rule
>> * simplify struct landlock_context by removing the arch and syscall_nr fields
>> * remove all eBPF map functions call, remove ABILITY_WRITE
>> * refactor bpf_landlock_func_proto() (suggested by Kees Cook)
>> * constify pointers
>> * fix doc inclusion
>>
>> Changes since v5:
>> * rename file hooks.c to init.c
>> * fix spelling
>>
>> Changes since v4:
>> * merge a minimal (not enabled) LSM code and Kconfig in this commit
>>
>> Changes since v3:
>> * split commit
>> * revamp the landlock_context:
>>   * add arch, syscall_nr and syscall_cmd (ioctl, fcntl…) to be able to
>> cross-check action with the event type
>>   * replace args array with dedicated fields to ease the addition of new
>> fields
>> ---
>>  include/linux/bpf_types.h  |  3 ++
>>  include/uapi/linux/bpf.h   | 97 
>> +
>>  security/Kconfig   |  1 +
>>  security/Makefile  |  2 +
>>  security/landlock/Kconfig  | 18 
>>  security/landlock/Makefile |  3 ++
>>  security/landlock/common.h | 21 +
>>  security/landlock/init.c   | 98 
>> ++
>>  tools/include/uapi/linux/bpf.h | 97 
>> +
>>  9 files changed, 340 insertions(+)
>>  create mode 100644 security/landlock/Kconfig
>>  create mode 100644 security/landlock/Makefile
>>  create mode 100644 security/landlock/common.h
>>  create mode 100644 security/landlock/init.c
>>
>> diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
>> index 6f1a567667b8..8bac93970a47 100644
>> --- a/include/linux/bpf_types.h
>> +++ b/include/linux/bpf_types.h
>> @@ -18,6 +18,9 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_KPROBE, kprobe_prog_ops)
>>  BPF_PROG_TYPE(BPF_PROG_TYPE_TRACEPOINT, tracepoint_prog_ops)
>>  BPF_PROG_TYPE(BPF_PROG_TYPE_PERF_EVENT, perf_event_prog_ops)
>>  #endif
>> +#ifdef CONFIG_SECURITY_LANDLOCK
>> +BPF_PROG_TYPE(BPF_PROG_TYPE_LANDLOCK_RULE, bpf_landlock_ops)
>> +#endif
>>  
>>  BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY, array_map_ops)
>>  BPF_MAP_TYPE(BPF_MAP_TYPE_PERCPU_ARRAY, percpu_array_map_ops)
>> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
>> index 8541ab85e432..20da634da941 100644
>> --- a/include/uapi/linux/bpf.h
>> +++ b/include/uapi/linux/bpf.h
>> @@ -129,6 +129,7 @@ enum bpf_prog_type {
>>  BPF_PROG_TYPE_LWT_XMIT,
>>  BPF_PROG_TYPE_SOCK_OPS,
>>  BPF_PROG_TYPE_SK_SKB,
>> +BPF_PROG_TYPE_LANDLOCK_RULE,
>>  };
>>  
>>  enum bpf_attach_type {
>> @@ -879,4 +880,100 @@ enum {
>>  #define TCP_BPF_IW  1001/* Set TCP initial congestion window */
>>  #define TCP_BPF_SNDCWND_CLAMP   1002/* Set sndcwnd_clamp */
>>  
>> +/**
>> + * enum landlock_subtype_event - event occurring when an action is 
>> performed on
>> + * a particular kernel object
>> + *
>> + * An event is a policy decision point which exposes the same context type
>> + * (especially the same arg[0-9] field types) for each rule execution.
>> + *
>> + * @LANDLOCK_SUBTYPE_EVENT_UNSPEC: invalid value
>> + * @LANDLOCK_SUBTYPE_EVENT_FS: generic filesystem event
>> + * @LANDLOCK_SUBTYPE_EVENT_FS_IOCTL: custom IOCTL sub-event
>> + * @LANDLOCK_SUBTYPE_EVENT_FS_LOCK: custo

Re: [PATCH net-next v7 01/10] selftest: Enhance kselftest_harness.h with a step mechanism

2017-08-25 Thread Mickaël Salaün


On 24/08/2017 04:31, Alexei Starovoitov wrote:
> On Mon, Aug 21, 2017 at 02:09:24AM +0200, Mickaël Salaün wrote:
>> This step mechanism may be useful to return an information about the
>> error without being able to write to TH_LOG_STREAM.
>>
>> Set _metadata->no_print to true to print this counter.
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>> Cc: Andy Lutomirski <l...@amacapital.net>
>> Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
>> Cc: Kees Cook <keesc...@chromium.org>
>> Cc: Shuah Khan <sh...@kernel.org>
>> Cc: Will Drewry <w...@chromium.org>
>> Link: 
>> https://lkml.kernel.org/r/cagxu5j+d-fp8kt9unnoqkrqjp4dytpmgkjxwykzyryivpz3...@mail.gmail.com
>> ---
>>
>> This patch is intended to the kselftest tree:
>> https://lkml.kernel.org/r/20170806232337.4191-1-...@digikod.net
>>
>> Changes since v6:
>> * add the step counter in assert/expect macros and use _metadata to
>>   enable the counter (suggested by Kees Cook)
>> ---
>>  tools/testing/selftests/kselftest_harness.h   | 31 
>> ++-
>>  tools/testing/selftests/seccomp/seccomp_bpf.c |  2 +-
>>  2 files changed, 27 insertions(+), 6 deletions(-)
> 
> is there a dependency on this in patches 2+ ?
> if not, I would send this patch to selftests right away.
> 
> 

The Landlock tests [patch 9/10] rely on it for now.

I sent it three weeks ago:
https://lkml.kernel.org/r/20170806232337.4191-1-...@digikod.net

Anyway, until this patch is merged in the kselftest tree and then
available to net-next, I'll have to keep it here.



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v7 02/10] bpf: Add eBPF program subtype and is_valid_subtype() verifier

2017-08-23 Thread Mickaël Salaün

On 23/08/2017 04:44, Alexei Starovoitov wrote:
> On Mon, Aug 21, 2017 at 02:09:25AM +0200, Mickaël Salaün wrote:
>> The goal of the program subtype is to be able to have different static
>> fine-grained verifications for a unique program type.
>>
>> The struct bpf_verifier_ops gets a new optional function:
>> is_valid_subtype(). This new verifier is called at the beginning of the
>> eBPF program verification to check if the (optional) program subtype is
>> valid.
>>
>> For now, only Landlock eBPF programs are using a program subtype (see
>> next commit) but this could be used by other program types in the future.
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>> Cc: Alexei Starovoitov <a...@kernel.org>
>> Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
>> Cc: Daniel Borkmann <dan...@iogearbox.net>
>> Cc: David S. Miller <da...@davemloft.net>
>> Link: 
>> https://lkml.kernel.org/r/20160827205559.ga43...@ast-mbp.thefacebook.com
>> ---
>>
>> Changes since v6:
>> * rename Landlock version to ABI to better reflect its purpose
>> * fix unsigned integer checks
>> * fix pointer cast
>> * constify pointers
>> * rebase
>>
>> Changes since v5:
>> * use a prog_subtype pointer and make it future-proof
>> * add subtype test
>> * constify bpf_load_program()'s subtype argument
>> * cleanup subtype initialization
>> * rebase
>>
>> Changes since v4:
>> * replace the "status" field with "version" (more generic)
>> * replace the "access" field with "ability" (less confusing)
>>
>> Changes since v3:
>> * remove the "origin" field
>> * add an "option" field
>> * cleanup comments
>> ---
>>  include/linux/bpf.h |  7 ++-
>>  include/linux/filter.h  |  2 +
>>  include/uapi/linux/bpf.h| 11 +
>>  kernel/bpf/syscall.c| 22 -
>>  kernel/bpf/verifier.c   | 17 +--
>>  kernel/trace/bpf_trace.c| 15 --
>>  net/core/filter.c   | 71 
>> ++---
>>  samples/bpf/bpf_load.c  |  3 +-
>>  samples/bpf/cookie_uid_helper_example.c |  2 +-
>>  samples/bpf/fds_example.c   |  2 +-
>>  samples/bpf/sock_example.c  |  3 +-
>>  samples/bpf/test_cgrp2_attach.c |  2 +-
>>  samples/bpf/test_cgrp2_attach2.c|  2 +-
>>  samples/bpf/test_cgrp2_sock.c   |  2 +-
>>  tools/include/uapi/linux/bpf.h  | 11 +
>>  tools/lib/bpf/bpf.c | 10 +++-
>>  tools/lib/bpf/bpf.h |  5 +-
>>  tools/lib/bpf/libbpf.c  |  4 +-
>>  tools/perf/tests/bpf.c  |  2 +-
>>  tools/testing/selftests/bpf/test_align.c|  2 +-
>>  tools/testing/selftests/bpf/test_tag.c  |  2 +-
>>  tools/testing/selftests/bpf/test_verifier.c | 17 ++-
>>  22 files changed, 158 insertions(+), 56 deletions(-)
> 
> ...
> 
>> diff --git a/include/linux/filter.h b/include/linux/filter.h
>> index 7015116331af..0c3fadbb5a58 100644
>> --- a/include/linux/filter.h
>> +++ b/include/linux/filter.h
>> @@ -464,6 +464,8 @@ struct bpf_prog {
>>  u32 len;/* Number of filter blocks */
>>  u32 jited_len;  /* Size of jited insns in bytes 
>> */
>>  u8  tag[BPF_TAG_SIZE];
>> +u8  has_subtype;
>> +union bpf_prog_subtype  subtype;/* Fine-grained verifications */
> 
> these burn a hole in very performance sensitive structure.
> Also there are bits rigth above. use them instead of u8 has_subtype?
> or can these two fields be part of bpf_prog_aux ?

OK, I'll create one bit variable and a bpf_prog_subtype field in the
bpf_prog_aux struct then.


> 
>>  struct bpf_prog_aux *aux;   /* Auxiliary fields */
>>  struct sock_fprog_kern  *orig_prog; /* Original BPF program */
>>  unsigned int(*bpf_func)(const void *ctx,
>> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
>> index 843818dff96d..8541ab85e432 100644
>> --- a/include/uapi/linux/bpf.h
>> +++ b/include/uapi/linux/bpf.h
>> @@ -177,6 +177,15 @@ enum bpf_attach_type {
>>  /* Specify numa node during map creation */
>>  #define BPF_F_NUMA_NODE (1U << 2)
>&

Re: [PATCH net-next v7 05/10] landlock: Add LSM hooks related to filesystem

2017-08-22 Thread Mickaël Salaün

On 21/08/2017 02:09, Mickaël Salaün wrote:
> Handle 33 filesystem-related LSM hooks for the Landlock filesystem
> event: LANDLOCK_SUBTYPE_EVENT_FS.
> 
> A Landlock event wrap LSM hooks for similar kernel object types (e.g.
> struct file, struct path...). Multiple LSM hooks can trigger the same
> Landlock event.
> 
> Landlock handle nine coarse-grained actions: read, write, execute, new,
> get, remove, ioctl, lock and fcntl. Each of them abstract LSM hook
> access control in a way that can be extended in the future.
> 
> The Landlock LSM hook registration is done after other LSM to only run
> actions from user-space, via eBPF programs, if the access was granted by
> major (privileged) LSMs.
> 
> Signed-off-by: Mickaël Salaün <m...@digikod.net>
> Cc: Alexei Starovoitov <a...@kernel.org>
> Cc: Andy Lutomirski <l...@amacapital.net>
> Cc: Daniel Borkmann <dan...@iogearbox.net>
> Cc: David S. Miller <da...@davemloft.net>
> Cc: James Morris <james.l.mor...@oracle.com>
> Cc: Kees Cook <keesc...@chromium.org>
> Cc: Serge E. Hallyn <se...@hallyn.com>
> ---
> 
> Changes since v6:
> * add 3 more sub-events: IOCTL, LOCK, FCNTL
>   https://lkml.kernel.org/r/2fbc99a6-f190-f335-bd14-04bdeed35...@digikod.net
> * use the new security_add_hooks()
> * explain the -Werror=unused-function
> * constify pointers
> * cleanup headers
> 
> Changes since v5:
> * split hooks.[ch] into hooks.[ch] and hooks_fs.[ch]
> * add more documentation
> * cosmetic fixes
> * rebase (SCALAR_VALUE)
> 
> Changes since v4:
> * add LSM hook abstraction called Landlock event
>   * use the compiler type checking to verify hooks use by an event
>   * handle all filesystem related LSM hooks (e.g. file_permission,
> mmap_file, sb_mount...)
> * register BPF programs for Landlock just after LSM hooks registration
> * move hooks registration after other LSMs
> * add failsafes to check if a hook is not used by the kernel
> * allow partial raw value access form the context (needed for programs
>   generated by LLVM)
> 
> Changes since v3:
> * split commit
> * add hooks dealing with struct inode and struct path pointers:
>   inode_permission and inode_getattr
> * add abstraction over eBPF helper arguments thanks to wrapping structs
> ---
>  include/linux/lsm_hooks.h|   5 +
>  security/landlock/Makefile   |   7 +-
>  security/landlock/common.h   |   2 +
>  security/landlock/hooks.c|  83 ++
>  security/landlock/hooks.h| 177 +
>  security/landlock/hooks_fs.c | 586 
> +++
>  security/landlock/hooks_fs.h |  19 ++
>  security/landlock/init.c |  10 +
>  security/security.c  |  12 +-
>  9 files changed, 899 insertions(+), 2 deletions(-)
>  create mode 100644 security/landlock/hooks.c
>  create mode 100644 security/landlock/hooks.h
>  create mode 100644 security/landlock/hooks_fs.c
>  create mode 100644 security/landlock/hooks_fs.h

> diff --git a/security/landlock/init.c b/security/landlock/init.c
> index 09acbc74abd6..1e6660fed697 100644
> --- a/security/landlock/init.c
> +++ b/security/landlock/init.c
> @@ -10,8 +10,10 @@
>  
>  #include  /* enum bpf_access_type */
>  #include  /* capable */
> +#include 
>  
>  #include "common.h" /* LANDLOCK_* */
> +#include "hooks_fs.h"
>  
>  
>  static inline bool bpf_landlock_is_valid_access(int off, int size,
> @@ -23,6 +25,8 @@ static inline bool bpf_landlock_is_valid_access(int off, 
> int size,
>  
>   switch (prog_subtype->landlock_rule.event) {
>   case LANDLOCK_SUBTYPE_EVENT_FS:
> + return landlock_is_valid_access_event_FS(off, size, type,
> + >reg_type, prog_subtype);

I forgot to handle LANDLOCK_SUBTYPE_EVENT_FS_{IOCTL,LOCK_FCNTL} here and
I included some hunks in the wrong patches. I will fix this in the next
series and add tests for those anyway. :)

Regards,
 Mickaël



signature.asc
Description: OpenPGP digital signature


[PATCH net-next v7 00/10] Landlock LSM: Toward unprivileged sandboxing

2017-08-20 Thread Mickaël Salaün
or now
* add user and kernel documentation
* rebase on net-next


# Changes since v3

* upstreamed patch:
  * commit 1955351da41c ("bpf: Set register type according to
is_valid_access()")
* use abstract LSM hook arguments with custom types (e.g. *_LANDLOCK_ARG_FS for
  struct file, struct inode and struct path)
* add more LSM hooks to support full filesystem access control
* improve the sandbox example
* fix races and RCU issues:
  * eBPF program execution and eBPF helpers
  * revamp the arraymap of handles to cleanly deal with update/delete
* eBPF program subtype for Landlock:
  * remove the "origin" field
  * add an "option" field
* rebase onto Daniel Mack's patches v7 [3]
* remove merged commit 1955351da41c ("bpf: Set register type according to
  is_valid_access()")
* fix spelling mistakes
* cleanup some type and variable names
* split patches
* for now, remove cgroup delegation handling for unprivileged user
* remove extra access check for cgroup_get_from_fd()
* remove unused example code dealing with skb
* remove seccomp-bpf link:
  * no more seccomp cookie
  * for now, it is no more possible to check the current syscall properties


# Changes since v2

* revamp cgroup handling:
  * use Daniel Mack's patches "Add eBPF hooks for cgroups" v5
  * remove bpf_landlock_cmp_cgroup_beneath()
  * make BPF_PROG_ATTACH usable with delegated cgroups
  * add a new CGRP_NO_NEW_PRIVS flag for safe cgroups
  * handle Landlock sandboxing for cgroups hierarchy
  * allow unprivileged processes to attach Landlock eBPF program to cgroups
* add subtype to eBPF programs:
  * replace Landlock hook identification by custom eBPF program types with a
dedicated subtype field
  * manage fine-grained privileged Landlock programs
  * register Landlock programs for dedicated trigger origins (e.g. syscall,
return from seccomp filter and/or interruption)
* performance and memory optimizations: use an array to access Landlock hooks
  directly but do not duplicated it for each thread (seccomp-based)
* allow running Landlock programs without seccomp filter
* fix seccomp-related issues
* remove extra errno bounding check for Landlock programs
* add some examples for optional eBPF functions or context access (network
  related) according to security checks to allow more features for privileged
  programs (e.g. Checmate)


# Changes since v1

* focus on the LSM hooks, not the syscalls:
  * much more simple implementation
  * does not need audit cache tricks to avoid race conditions
  * more simple to use and more generic because using the LSM hook abstraction
directly
  * more efficient because only checking in LSM hooks
  * architecture agnostic
* switch from cBPF to eBPF:
  * new eBPF program types dedicated to Landlock
  * custom functions used by the eBPF program
  * gain some new features (e.g. 10 registers, can load values of different
size, LLVM translator) but only a few functions allowed and a dedicated 
map
type
  * new context: LSM hook ID, cookie and LSM hook arguments
  * need to set the sysctl kernel.unprivileged_bpf_disable to 0 (default value)
to be able to load hook filters as unprivileged users
* smaller and simpler:
  * no more checker groups but dedicated arraymap of handles
  * simpler userland structs thanks to eBPF functions
* distinctive name: Landlock


[1] https://lkml.kernel.org/r/20170328234650.19695-1-...@digikod.net
[2] https://lkml.kernel.org/r/5828776a.1010...@digikod.net
[3] 
https://lkml.kernel.org/r/1477390454-12553-1-git-send-email-dan...@zonque.org
[4] 
https://lkml.kernel.org/r/20160829114542.GA20836@ircssh.c.rugged-nimbus-611.internal
[5] https://lkml.kernel.org/r/20161221231506.19800-1-...@digikod.net
[6] https://lkml.kernel.org/r/2fbc99a6-f190-f335-bd14-04bdeed35...@digikod.net
[7] https://lkml.kernel.org/r/20170806232337.4191-1-...@digikod.net

Regards,

Mickaël Salaün (10):
  selftest: Enhance kselftest_harness.h with a step mechanism
  bpf: Add eBPF program subtype and is_valid_subtype() verifier
  bpf,landlock: Define an eBPF program type for a Landlock rule
  bpf: Define handle_fs and add a new helper bpf_handle_fs_get_mode()
  landlock: Add LSM hooks related to filesystem
  seccomp,landlock: Handle Landlock events per process hierarchy
  landlock: Add ptrace restrictions
  bpf: Add a Landlock sandbox example
  bpf,landlock: Add tests for Landlock
  landlock: Add user and kernel documentation for Landlock

 Documentation/security/index.rst   |   1 +
 Documentation/security/landlock/index.rst  |  19 +
 Documentation/security/landlock/kernel.rst | 132 +
 Documentation/security/landlock/user.rst   | 313 +++
 include/linux/bpf.h|  38 +-
 include/linux/bpf_types.h  |   3 +
 include/linux/filter.h |   2 +
 include/linux/landlock.h   |  42 ++
 include/linux/lsm_hooks.

[PATCH net-next v7 07/10] landlock: Add ptrace restrictions

2017-08-20 Thread Mickaël Salaün
A landlocked process has less privileges than a non-landlocked process
and must then be subject to additional restrictions when manipulating
processes. To be allowed to use ptrace(2) and related syscalls on a
target process, a landlocked process must have a subset of the target
process' rules.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---

Changes since v6:
* factor out ptrace check
* constify pointers
* cleanup headers
* use the new security_add_hooks()
---
 security/landlock/Makefile   |   2 +-
 security/landlock/hooks_ptrace.c | 123 +++
 security/landlock/hooks_ptrace.h |  11 
 security/landlock/init.c |   2 +
 4 files changed, 137 insertions(+), 1 deletion(-)
 create mode 100644 security/landlock/hooks_ptrace.c
 create mode 100644 security/landlock/hooks_ptrace.h

diff --git a/security/landlock/Makefile b/security/landlock/Makefile
index 8153b024ffd7..7ff911328e74 100644
--- a/security/landlock/Makefile
+++ b/security/landlock/Makefile
@@ -5,4 +5,4 @@ ccflags-$(CONFIG_SECURITY_LANDLOCK) += -Werror=unused-function
 
 obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o
 
-landlock-y := init.o providers.o hooks.o hooks_fs.o
+landlock-y := init.o providers.o hooks.o hooks_ptrace.o hooks_fs.o
diff --git a/security/landlock/hooks_ptrace.c b/security/landlock/hooks_ptrace.c
new file mode 100644
index ..0f1c13172f54
--- /dev/null
+++ b/security/landlock/hooks_ptrace.c
@@ -0,0 +1,123 @@
+/*
+ * Landlock LSM - ptrace hooks
+ *
+ * Copyright © 2017 Mickaël Salaün <m...@digikod.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include  /* ARRAY_SIZE */
+#include 
+#include  /* struct task_struct */
+#include 
+
+#include "common.h" /* struct landlock_events */
+#include "hooks.h" /* landlocked() */
+#include "hooks_ptrace.h"
+
+
+static bool landlock_events_are_subset(const struct landlock_events *parent,
+   const struct landlock_events *child)
+{
+   size_t i;
+
+   if (!parent || !child)
+   return false;
+   if (parent == child)
+   return true;
+
+   for (i = 0; i < ARRAY_SIZE(child->rules); i++) {
+   struct landlock_rule *walker;
+   bool found_parent = false;
+
+   if (!parent->rules[i])
+   continue;
+   for (walker = child->rules[i]; walker; walker = walker->prev) {
+   if (walker == parent->rules[i]) {
+   found_parent = true;
+   break;
+   }
+   }
+   if (!found_parent)
+   return false;
+   }
+   return true;
+}
+
+static bool landlock_task_has_subset_events(const struct task_struct *parent,
+   const struct task_struct *child)
+{
+#ifdef CONFIG_SECCOMP_FILTER
+   if (landlock_events_are_subset(parent->seccomp.landlock_events,
+   child->seccomp.landlock_events))
+   /* must be ANDed with other providers (i.e. cgroup) */
+   return true;
+#endif /* CONFIG_SECCOMP_FILTER */
+   return false;
+}
+
+static int landlock_task_ptrace(const struct task_struct *parent,
+   const struct task_struct *child)
+{
+   if (!landlocked(parent))
+   return 0;
+
+   if (!landlocked(child))
+   return -EPERM;
+
+   if (landlock_task_has_subset_events(parent, child))
+   return 0;
+
+   return -EPERM;
+}
+
+/**
+ * landlock_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 has Landlock rules, then the child must have at least
+ * the same rules.  Else denied.
+ *
+ * Determine whether a process may access another, returning 0 if permission
+ * granted, -errno if denied.
+ */
+static int landlock_ptrace_access_check(struct task_struct *child,
+   unsigned int mode)
+{
+   return landlock_task_ptrace(current, child);
+}
+
+/**
+ * landlock_ptrace_traceme - determine whether another process may trace the
+ *  current one
+ *
+ * @parent: the task proposed to be the tracer
+ *
+ * If the parent has Landlock rules, then the current task must have the same
+ * or more rules.
+ * Else den

[PATCH net-next v7 09/10] bpf,landlock: Add tests for Landlock

2017-08-20 Thread Mickaël Salaün
Test basic context access, ptrace protection and filesystem event with
multiple cases.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
Cc: Shuah Khan <sh...@kernel.org>
Cc: Will Drewry <w...@chromium.org>
---

Changes since v6:
* use the new kselftest_harness.h
* use const variables
* replace ASSERT_STEP with ASSERT_*
* rename BPF_PROG_TYPE_LANDLOCK to BPF_PROG_TYPE_LANDLOCK_RULE
* force sample library rebuild
* fix install target

Changes since v5:
* add subtype test
* add ptrace tests
* split and rename files
* cleanup and rebase
---
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/bpf/test_verifier.c|  55 
 tools/testing/selftests/landlock/.gitignore|   5 +
 tools/testing/selftests/landlock/Makefile  |  48 
 tools/testing/selftests/landlock/bpf/Makefile  |  55 
 tools/testing/selftests/landlock/bpf/README.rst|   1 +
 .../selftests/landlock/bpf/rule_fs_no_open.c   |  32 +++
 .../selftests/landlock/bpf/rule_fs_read_only.c |  32 +++
 tools/testing/selftests/landlock/test.h|  28 ++
 tools/testing/selftests/landlock/test_base.c   |  27 ++
 tools/testing/selftests/landlock/test_fs.c | 296 +
 tools/testing/selftests/landlock/test_ptrace.c | 158 +++
 12 files changed, 738 insertions(+)
 create mode 100644 tools/testing/selftests/landlock/.gitignore
 create mode 100644 tools/testing/selftests/landlock/Makefile
 create mode 100644 tools/testing/selftests/landlock/bpf/Makefile
 create mode 12 tools/testing/selftests/landlock/bpf/README.rst
 create mode 100644 tools/testing/selftests/landlock/bpf/rule_fs_no_open.c
 create mode 100644 tools/testing/selftests/landlock/bpf/rule_fs_read_only.c
 create mode 100644 tools/testing/selftests/landlock/test.h
 create mode 100644 tools/testing/selftests/landlock/test_base.c
 create mode 100644 tools/testing/selftests/landlock/test_fs.c
 create mode 100644 tools/testing/selftests/landlock/test_ptrace.c

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 26ce4f7168be..099d19950739 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -12,6 +12,7 @@ TARGETS += gpio
 TARGETS += intel_pstate
 TARGETS += ipc
 TARGETS += kcmp
+TARGETS += landlock
 TARGETS += lib
 TARGETS += membarrier
 TARGETS += memfd
diff --git a/tools/testing/selftests/bpf/test_verifier.c 
b/tools/testing/selftests/bpf/test_verifier.c
index 3146839a51bf..9fb19c975c1b 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -6499,6 +6499,61 @@ static struct bpf_test tests[] = {
.result = REJECT,
.has_prog_subtype = true,
},
+   {
+   "missing subtype",
+   .insns = {
+   BPF_MOV32_IMM(BPF_REG_0, 0),
+   BPF_EXIT_INSN(),
+   },
+   .errstr = "",
+   .result = REJECT,
+   .prog_type = BPF_PROG_TYPE_LANDLOCK_RULE,
+   },
+   {
+   "landlock/fs: always accept",
+   .insns = {
+   BPF_MOV32_IMM(BPF_REG_0, 0),
+   BPF_EXIT_INSN(),
+   },
+   .result = ACCEPT,
+   .prog_type = BPF_PROG_TYPE_LANDLOCK_RULE,
+   .has_prog_subtype = true,
+   .prog_subtype = {
+   .landlock_rule = {
+   .abi = 1,
+   .event = LANDLOCK_SUBTYPE_EVENT_FS,
+   }
+   },
+   },
+   {
+   "landlock/fs: read context",
+   .insns = {
+   BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
+   BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, status)),
+   /* test operations on raw values */
+   BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1),
+   BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, event)),
+   BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1),
+   BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, arg1)),
+   BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, arg2)),
+   BPF_ALU64_IMM(BPF_ADD, BPF_R

[PATCH net-next v7 08/10] bpf: Add a Landlock sandbox example

2017-08-20 Thread Mickaël Salaün
Add a basic sandbox tool to create a process isolated from some part of
the system. This sandbox create a read-only environment. It is only
allowed to write to a character device such as a TTY:

  # :> X
  # echo $?
  0
  # ./samples/bpf/landlock1 /bin/sh -i
  Launching a new sandboxed process.
  # :> Y
  cannot create Y: Operation not permitted

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---

Changes since v6:
* check return value of load_and_attach()
* allow to write on pipes
* rename BPF_PROG_TYPE_LANDLOCK to BPF_PROG_TYPE_LANDLOCK_RULE
* rename Landlock version to ABI to better reflect its purpose
* use const variable (suggested by Kees Cook)
* remove useless definitions (suggested by Kees Cook)
* add detailed explanations (suggested by Kees Cook)

Changes since v5:
* cosmetic fixes
* rebase

Changes since v4:
* write Landlock rule in C and compiled it with LLVM
* remove cgroup handling
* remove path handling: only handle a read-only environment
* remove errno return codes

Changes since v3:
* remove seccomp and origin field: completely free from seccomp programs
* handle more FS-related hooks
* handle inode hooks and directory traversal
* add faked but consistent view thanks to ENOENT
* add /lib64 in the example
* fix spelling
* rename some types and definitions (e.g. SECCOMP_ADD_LANDLOCK_RULE)

Changes since v2:
* use BPF_PROG_ATTACH for cgroup handling
---
 samples/bpf/Makefile |   4 ++
 samples/bpf/bpf_load.c   |  28 ++--
 samples/bpf/landlock1_kern.c | 100 +++
 samples/bpf/landlock1_user.c | 100 +++
 4 files changed, 229 insertions(+), 3 deletions(-)
 create mode 100644 samples/bpf/landlock1_kern.c
 create mode 100644 samples/bpf/landlock1_user.c

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index f1010fe759fe..08d5d728e3e0 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -40,6 +40,7 @@ hostprogs-y += load_sock_ops
 hostprogs-y += xdp_redirect
 hostprogs-y += xdp_redirect_map
 hostprogs-y += syscall_tp
+hostprogs-y += landlock1
 
 # Libbpf dependencies
 LIBBPF := ../../tools/lib/bpf/bpf.o
@@ -84,6 +85,7 @@ per_socket_stats_example-objs := $(LIBBPF) 
cookie_uid_helper_example.o
 xdp_redirect-objs := bpf_load.o $(LIBBPF) xdp_redirect_user.o
 xdp_redirect_map-objs := bpf_load.o $(LIBBPF) xdp_redirect_map_user.o
 syscall_tp-objs := bpf_load.o $(LIBBPF) syscall_tp_user.o
+landlock1-objs := bpf_load.o $(LIBBPF) landlock1_user.o
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
@@ -128,6 +130,7 @@ always += tcp_clamp_kern.o
 always += xdp_redirect_kern.o
 always += xdp_redirect_map_kern.o
 always += syscall_tp_kern.o
+always += landlock1_kern.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 HOSTCFLAGS += -I$(srctree)/tools/lib/
@@ -167,6 +170,7 @@ HOSTLOADLIBES_test_map_in_map += -lelf
 HOSTLOADLIBES_xdp_redirect += -lelf
 HOSTLOADLIBES_xdp_redirect_map += -lelf
 HOSTLOADLIBES_syscall_tp += -lelf
+HOSTLOADLIBES_landlock1 += -lelf
 
 # Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on 
cmdline:
 #  make samples/bpf/ LLC=~/git/llvm/build/bin/llc 
CLANG=~/git/llvm/build/bin/clang
diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index 01a506f768da..30fcddda8b81 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -31,6 +31,8 @@
 
 static char license[128];
 static int kern_version;
+static union bpf_prog_subtype subtype = {};
+static bool has_subtype;
 static bool processed_sec[128];
 char bpf_log_buf[BPF_LOG_BUF_SIZE];
 int map_fd[MAX_MAPS];
@@ -66,6 +68,7 @@ static int load_and_attach(const char *event, struct bpf_insn 
*prog, int size)
bool is_cgroup_sk = strncmp(event, "cgroup/sock", 11) == 0;
bool is_sockops = strncmp(event, "sockops", 7) == 0;
bool is_sk_skb = strncmp(event, "sk_skb", 6) == 0;
+   bool is_landlock = strncmp(event, "landlock", 8) == 0;
size_t insns_cnt = size / sizeof(struct bpf_insn);
enum bpf_prog_type prog_type;
char buf[256];
@@ -96,6 +99,13 @@ static int load_and_attach(const char *event, struct 
bpf_insn *prog, int size)
prog_type = BPF_PROG_TYPE_SOCK_OPS;
} else if (is_sk_skb) {
prog_type = BPF_PROG_TYPE_SK_SKB;
+   } else if (is_landlock) {
+   prog_type = BPF_PROG_TYPE_LANDLOCK_RULE;
+   if (!has_subtype) {
+   printf("No subtype\n");
+   return -1;
+   }
+   st = 
} else {
printf("U

[PATCH net-next v7 10/10] landlock: Add user and kernel documentation for Landlock

2017-08-20 Thread Mickaël Salaün
This documentation can be built with the Sphinx framework.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Jonathan Corbet <cor...@lwn.net>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---

Changes since v6:
* add a check for ctx->event
* rename BPF_PROG_TYPE_LANDLOCK to BPF_PROG_TYPE_LANDLOCK_RULE
* rename Landlock version to ABI to better reflect its purpose and add a
  dedicated changelog section
* update tables
* relax no_new_privs recommendations
* remove ABILITY_WRITE related functions
* reword rule "appending" to "prepending" and explain it
* cosmetic fixes

Changes since v5:
* update the rule hierarchy inheritance explanation
* briefly explain ctx->arg2
* add ptrace restrictions
* explain EPERM
* update example (subtype)
* use ":manpage:"
---
 Documentation/security/index.rst   |   1 +
 Documentation/security/landlock/index.rst  |  19 ++
 Documentation/security/landlock/kernel.rst | 132 
 Documentation/security/landlock/user.rst   | 313 +
 4 files changed, 465 insertions(+)
 create mode 100644 Documentation/security/landlock/index.rst
 create mode 100644 Documentation/security/landlock/kernel.rst
 create mode 100644 Documentation/security/landlock/user.rst

diff --git a/Documentation/security/index.rst b/Documentation/security/index.rst
index 298a94a33f05..1db294025d0f 100644
--- a/Documentation/security/index.rst
+++ b/Documentation/security/index.rst
@@ -11,3 +11,4 @@ Security Documentation
LSM
self-protection
tpm/index
+   landlock/index
diff --git a/Documentation/security/landlock/index.rst 
b/Documentation/security/landlock/index.rst
new file mode 100644
index ..8afde6a5805c
--- /dev/null
+++ b/Documentation/security/landlock/index.rst
@@ -0,0 +1,19 @@
+=
+Landlock LSM: programmatic access control
+=
+
+Landlock is a stackable Linux Security Module (LSM) that makes it possible to
+create security sandboxes.  This kind of sandbox is expected to help mitigate
+the security impact of bugs or unexpected/malicious behaviors in user-space
+applications.  The current version allows only a process with the global
+CAP_SYS_ADMIN capability to create such sandboxes but the ultimate goal of
+Landlock is to empower any process, including unprivileged ones, to securely
+restrict themselves.  Landlock is inspired by seccomp-bpf but instead of
+filtering syscalls and their raw arguments, a Landlock rule can inspect the use
+of kernel objects like files and hence make a decision according to the kernel
+semantic.
+
+.. toctree::
+
+user
+kernel
diff --git a/Documentation/security/landlock/kernel.rst 
b/Documentation/security/landlock/kernel.rst
new file mode 100644
index ..560711835ce8
--- /dev/null
+++ b/Documentation/security/landlock/kernel.rst
@@ -0,0 +1,132 @@
+==
+Landlock: kernel documentation
+==
+
+eBPF properties
+===
+
+To get an expressive language while still being safe and small, Landlock is
+based on eBPF. Landlock should be usable by untrusted processes and must
+therefore expose a minimal attack surface. The eBPF bytecode is minimal,
+powerful, widely used and designed to be used by untrusted applications. Thus,
+reusing the eBPF support in the kernel enables a generic approach while
+minimizing new code.
+
+An eBPF program has access to an eBPF context containing some fields including
+event arguments (i.e. arg1 and arg2). These arguments can be used directly or
+passed to helper functions according to their types. It is then possible to do
+complex access checks without race conditions or inconsistent evaluation (i.e.
+`incorrect mirroring of the OS code and state
+<https://www.internetsociety.org/doc/traps-and-pitfalls-practical-problems-system-call-interposition-based-security-tools>`_).
+
+A Landlock event describes a particular access type.  For now, there is only
+one event type dedicated to filesystem related operations:
+LANDLOCK_SUBTYPE_EVENT_FS.  A Landlock rule is tied to one event type.  This
+makes it possible to statically check context accesses, potentially performed
+by such rule, and hence prevents kernel address leaks and ensure the right use
+of event arguments with eBPF functions.  Any user can add multiple Landlock
+rules per Landlock event.  They are stacked and evaluated one after the other,
+starting from the most recent rule, as seccomp-bpf does with its filters.
+Underneath, an event is an abstraction over a set of LSM hooks.
+
+
+Guiding principles
+==
+
+Unprivileged use

[PATCH net-next v7 02/10] bpf: Add eBPF program subtype and is_valid_subtype() verifier

2017-08-20 Thread Mickaël Salaün
The goal of the program subtype is to be able to have different static
fine-grained verifications for a unique program type.

The struct bpf_verifier_ops gets a new optional function:
is_valid_subtype(). This new verifier is called at the beginning of the
eBPF program verification to check if the (optional) program subtype is
valid.

For now, only Landlock eBPF programs are using a program subtype (see
next commit) but this could be used by other program types in the future.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Link: https://lkml.kernel.org/r/20160827205559.ga43...@ast-mbp.thefacebook.com
---

Changes since v6:
* rename Landlock version to ABI to better reflect its purpose
* fix unsigned integer checks
* fix pointer cast
* constify pointers
* rebase

Changes since v5:
* use a prog_subtype pointer and make it future-proof
* add subtype test
* constify bpf_load_program()'s subtype argument
* cleanup subtype initialization
* rebase

Changes since v4:
* replace the "status" field with "version" (more generic)
* replace the "access" field with "ability" (less confusing)

Changes since v3:
* remove the "origin" field
* add an "option" field
* cleanup comments
---
 include/linux/bpf.h |  7 ++-
 include/linux/filter.h  |  2 +
 include/uapi/linux/bpf.h| 11 +
 kernel/bpf/syscall.c| 22 -
 kernel/bpf/verifier.c   | 17 +--
 kernel/trace/bpf_trace.c| 15 --
 net/core/filter.c   | 71 ++---
 samples/bpf/bpf_load.c  |  3 +-
 samples/bpf/cookie_uid_helper_example.c |  2 +-
 samples/bpf/fds_example.c   |  2 +-
 samples/bpf/sock_example.c  |  3 +-
 samples/bpf/test_cgrp2_attach.c |  2 +-
 samples/bpf/test_cgrp2_attach2.c|  2 +-
 samples/bpf/test_cgrp2_sock.c   |  2 +-
 tools/include/uapi/linux/bpf.h  | 11 +
 tools/lib/bpf/bpf.c | 10 +++-
 tools/lib/bpf/bpf.h |  5 +-
 tools/lib/bpf/libbpf.c  |  4 +-
 tools/perf/tests/bpf.c  |  2 +-
 tools/testing/selftests/bpf/test_align.c|  2 +-
 tools/testing/selftests/bpf/test_tag.c  |  2 +-
 tools/testing/selftests/bpf/test_verifier.c | 17 ++-
 22 files changed, 158 insertions(+), 56 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 830f472d8df5..aef2e6f6d763 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -159,13 +159,15 @@ bpf_ctx_record_field_size(struct bpf_insn_access_aux 
*aux, u32 size)
 
 struct bpf_verifier_ops {
/* return eBPF function prototype for verification */
-   const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id 
func_id);
+   const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id func_id,
+ const union bpf_prog_subtype 
*prog_subtype);
 
/* return true if 'size' wide access at offset 'off' within bpf_context
 * with 'type' (read or write) is allowed
 */
bool (*is_valid_access)(int off, int size, enum bpf_access_type type,
-   struct bpf_insn_access_aux *info);
+   struct bpf_insn_access_aux *info,
+   const union bpf_prog_subtype *prog_subtype);
int (*gen_prologue)(struct bpf_insn *insn, bool direct_write,
const struct bpf_prog *prog);
u32 (*convert_ctx_access)(enum bpf_access_type type,
@@ -174,6 +176,7 @@ struct bpf_verifier_ops {
  struct bpf_prog *prog, u32 *target_size);
int (*test_run)(struct bpf_prog *prog, const union bpf_attr *kattr,
union bpf_attr __user *uattr);
+   bool (*is_valid_subtype)(const union bpf_prog_subtype *prog_subtype);
 };
 
 struct bpf_prog_aux {
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 7015116331af..0c3fadbb5a58 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -464,6 +464,8 @@ struct bpf_prog {
u32 len;/* Number of filter blocks */
u32 jited_len;  /* Size of jited insns in bytes 
*/
u8  tag[BPF_TAG_SIZE];
+   u8  has_subtype;
+   union bpf_prog_subtype  subtype;/* Fine-grained verifications */
struct bpf_prog_aux *aux;   /* Auxiliary fields */
struct sock_fprog_kern  *orig_prog; /* Original BPF program */
unsigned int   

[PATCH net-next v7 01/10] selftest: Enhance kselftest_harness.h with a step mechanism

2017-08-20 Thread Mickaël Salaün
This step mechanism may be useful to return an information about the
error without being able to write to TH_LOG_STREAM.

Set _metadata->no_print to true to print this counter.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Shuah Khan <sh...@kernel.org>
Cc: Will Drewry <w...@chromium.org>
Link: 
https://lkml.kernel.org/r/cagxu5j+d-fp8kt9unnoqkrqjp4dytpmgkjxwykzyryivpz3...@mail.gmail.com
---

This patch is intended to the kselftest tree:
https://lkml.kernel.org/r/20170806232337.4191-1-...@digikod.net

Changes since v6:
* add the step counter in assert/expect macros and use _metadata to
  enable the counter (suggested by Kees Cook)
---
 tools/testing/selftests/kselftest_harness.h   | 31 ++-
 tools/testing/selftests/seccomp/seccomp_bpf.c |  2 +-
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/kselftest_harness.h 
b/tools/testing/selftests/kselftest_harness.h
index c56f72e07cd7..850ff6946027 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -51,6 +51,9 @@
 #define __KSELFTEST_HARNESS_H
 
 #define _GNU_SOURCE
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -555,12 +558,18 @@
  * return while still providing an optional block to the API consumer.
  */
 #define OPTIONAL_HANDLER(_assert) \
-   for (; _metadata->trigger;  _metadata->trigger = __bail(_assert))
+   for (; _metadata->trigger; _metadata->trigger = \
+   __bail(_assert, _metadata->no_print, _metadata->step))
+
+#define __INC_STEP(_metadata) \
+   if (_metadata->passed && _metadata->step < 255) \
+   _metadata->step++;
 
 #define __EXPECT(_expected, _seen, _t, _assert) do { \
/* Avoid multiple evaluation of the cases */ \
__typeof__(_expected) __exp = (_expected); \
__typeof__(_seen) __seen = (_seen); \
+   __INC_STEP(_metadata); \
if (!(__exp _t __seen)) { \
unsigned long long __exp_print = (uintptr_t)__exp; \
unsigned long long __seen_print = (uintptr_t)__seen; \
@@ -576,6 +585,7 @@
 #define __EXPECT_STR(_expected, _seen, _t, _assert) do { \
const char *__exp = (_expected); \
const char *__seen = (_seen); \
+   __INC_STEP(_metadata); \
if (!(strcmp(__exp, __seen) _t 0))  { \
__TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \
_metadata->passed = 0; \
@@ -590,6 +600,8 @@ struct __test_metadata {
int termsig;
int passed;
int trigger; /* extra handler after the evaluation */
+   __u8 step;
+   bool no_print; /* manual trigger when TH_LOG_STREAM is not available */
struct __test_metadata *prev, *next;
 };
 
@@ -634,10 +646,13 @@ static inline void __register_test(struct __test_metadata 
*t)
}
 }
 
-static inline int __bail(int for_realz)
+static inline int __bail(int for_realz, bool no_print, __u8 step)
 {
-   if (for_realz)
+   if (for_realz) {
+   if (no_print)
+   _exit(step);
abort();
+   }
return 0;
 }
 
@@ -655,18 +670,24 @@ void __run_test(struct __test_metadata *t)
t->passed = 0;
} else if (child_pid == 0) {
t->fn(t);
-   _exit(t->passed);
+   /* return the step that failed or 0 */
+   _exit(t->passed ? 0 : t->step);
} else {
/* TODO(wad) add timeout support. */
waitpid(child_pid, , 0);
if (WIFEXITED(status)) {
-   t->passed = t->termsig == -1 ? WEXITSTATUS(status) : 0;
+   t->passed = t->termsig == -1 ? !WEXITSTATUS(status) : 0;
if (t->termsig != -1) {
fprintf(TH_LOG_STREAM,
"%s: Test exited normally "
"instead of by signal (code: %d)\n",
t->name,
WEXITSTATUS(status));
+   } else if (!t->passed) {
+   fprintf(TH_LOG_STREAM,
+   "%s: Test failed at step #%d\n",
+   t->name,
+   WEXITSTATUS(status));
}
} else if (WIFSIGNALED(status)) {
t->passed = 0;
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c 
b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 73f5ea6778ce..4d6f92a9df6b 100644
--- a/tools/

[PATCH net-next v7 03/10] bpf,landlock: Define an eBPF program type for a Landlock rule

2017-08-20 Thread Mickaël Salaün
Add a new type of eBPF program used by Landlock rules.

This new BPF program type will be registered with the Landlock LSM
initialization.

Add an initial Landlock Kconfig.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---

Changes since v6:
* add 3 more sub-events: IOCTL, LOCK, FCNTL
  https://lkml.kernel.org/r/2fbc99a6-f190-f335-bd14-04bdeed35...@digikod.net
* rename LANDLOCK_VERSION to LANDLOCK_ABI to better reflect its purpose,
  and move it from landlock.h to common.h
* rename BPF_PROG_TYPE_LANDLOCK to BPF_PROG_TYPE_LANDLOCK_RULE: an eBPF
  program could be used for something else than a rule
* simplify struct landlock_context by removing the arch and syscall_nr fields
* remove all eBPF map functions call, remove ABILITY_WRITE
* refactor bpf_landlock_func_proto() (suggested by Kees Cook)
* constify pointers
* fix doc inclusion

Changes since v5:
* rename file hooks.c to init.c
* fix spelling

Changes since v4:
* merge a minimal (not enabled) LSM code and Kconfig in this commit

Changes since v3:
* split commit
* revamp the landlock_context:
  * add arch, syscall_nr and syscall_cmd (ioctl, fcntl…) to be able to
cross-check action with the event type
  * replace args array with dedicated fields to ease the addition of new
fields
---
 include/linux/bpf_types.h  |  3 ++
 include/uapi/linux/bpf.h   | 97 +
 security/Kconfig   |  1 +
 security/Makefile  |  2 +
 security/landlock/Kconfig  | 18 
 security/landlock/Makefile |  3 ++
 security/landlock/common.h | 21 +
 security/landlock/init.c   | 98 ++
 tools/include/uapi/linux/bpf.h | 97 +
 9 files changed, 340 insertions(+)
 create mode 100644 security/landlock/Kconfig
 create mode 100644 security/landlock/Makefile
 create mode 100644 security/landlock/common.h
 create mode 100644 security/landlock/init.c

diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
index 6f1a567667b8..8bac93970a47 100644
--- a/include/linux/bpf_types.h
+++ b/include/linux/bpf_types.h
@@ -18,6 +18,9 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_KPROBE, kprobe_prog_ops)
 BPF_PROG_TYPE(BPF_PROG_TYPE_TRACEPOINT, tracepoint_prog_ops)
 BPF_PROG_TYPE(BPF_PROG_TYPE_PERF_EVENT, perf_event_prog_ops)
 #endif
+#ifdef CONFIG_SECURITY_LANDLOCK
+BPF_PROG_TYPE(BPF_PROG_TYPE_LANDLOCK_RULE, bpf_landlock_ops)
+#endif
 
 BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY, array_map_ops)
 BPF_MAP_TYPE(BPF_MAP_TYPE_PERCPU_ARRAY, percpu_array_map_ops)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 8541ab85e432..20da634da941 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -129,6 +129,7 @@ enum bpf_prog_type {
BPF_PROG_TYPE_LWT_XMIT,
BPF_PROG_TYPE_SOCK_OPS,
BPF_PROG_TYPE_SK_SKB,
+   BPF_PROG_TYPE_LANDLOCK_RULE,
 };
 
 enum bpf_attach_type {
@@ -879,4 +880,100 @@ enum {
 #define TCP_BPF_IW 1001/* Set TCP initial congestion window */
 #define TCP_BPF_SNDCWND_CLAMP  1002/* Set sndcwnd_clamp */
 
+/**
+ * enum landlock_subtype_event - event occurring when an action is performed on
+ * a particular kernel object
+ *
+ * An event is a policy decision point which exposes the same context type
+ * (especially the same arg[0-9] field types) for each rule execution.
+ *
+ * @LANDLOCK_SUBTYPE_EVENT_UNSPEC: invalid value
+ * @LANDLOCK_SUBTYPE_EVENT_FS: generic filesystem event
+ * @LANDLOCK_SUBTYPE_EVENT_FS_IOCTL: custom IOCTL sub-event
+ * @LANDLOCK_SUBTYPE_EVENT_FS_LOCK: custom LOCK sub-event
+ * @LANDLOCK_SUBTYPE_EVENT_FS_FCNTL: custom FCNTL sub-event
+ */
+enum landlock_subtype_event {
+   LANDLOCK_SUBTYPE_EVENT_UNSPEC,
+   LANDLOCK_SUBTYPE_EVENT_FS,
+   LANDLOCK_SUBTYPE_EVENT_FS_IOCTL,
+   LANDLOCK_SUBTYPE_EVENT_FS_LOCK,
+   LANDLOCK_SUBTYPE_EVENT_FS_FCNTL,
+};
+#define _LANDLOCK_SUBTYPE_EVENT_LAST LANDLOCK_SUBTYPE_EVENT_FS_FCNTL
+
+/**
+ * DOC: landlock_subtype_ability
+ *
+ * eBPF context and functions allowed for a rule
+ *
+ * - LANDLOCK_SUBTYPE_ABILITY_DEBUG: allows to do debug actions (e.g. writing
+ *   logs), which may be dangerous and should only be used for rule testing
+ */
+#define LANDLOCK_SUBTYPE_ABILITY_DEBUG (1ULL << 0)
+#define _LANDLOCK_SUBTYPE_ABILITY_NB   1
+#define _LANDLOCK_SUBTYPE_ABILITY_MASK ((1ULL << 
_LANDLOCK_SUBTYPE_ABILITY_NB) - 1)
+
+/*
+ * Future options for a Landlock rule (e.g. run even if a previous rule denied
+ * an action).
+ */
+#define _LANDLOCK_SUBTYPE_OPTION_NB0
+#define _LANDLOCK_SUBTYPE_OPTI

[PATCH net-next v7 05/10] landlock: Add LSM hooks related to filesystem

2017-08-20 Thread Mickaël Salaün
Handle 33 filesystem-related LSM hooks for the Landlock filesystem
event: LANDLOCK_SUBTYPE_EVENT_FS.

A Landlock event wrap LSM hooks for similar kernel object types (e.g.
struct file, struct path...). Multiple LSM hooks can trigger the same
Landlock event.

Landlock handle nine coarse-grained actions: read, write, execute, new,
get, remove, ioctl, lock and fcntl. Each of them abstract LSM hook
access control in a way that can be extended in the future.

The Landlock LSM hook registration is done after other LSM to only run
actions from user-space, via eBPF programs, if the access was granted by
major (privileged) LSMs.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---

Changes since v6:
* add 3 more sub-events: IOCTL, LOCK, FCNTL
  https://lkml.kernel.org/r/2fbc99a6-f190-f335-bd14-04bdeed35...@digikod.net
* use the new security_add_hooks()
* explain the -Werror=unused-function
* constify pointers
* cleanup headers

Changes since v5:
* split hooks.[ch] into hooks.[ch] and hooks_fs.[ch]
* add more documentation
* cosmetic fixes
* rebase (SCALAR_VALUE)

Changes since v4:
* add LSM hook abstraction called Landlock event
  * use the compiler type checking to verify hooks use by an event
  * handle all filesystem related LSM hooks (e.g. file_permission,
mmap_file, sb_mount...)
* register BPF programs for Landlock just after LSM hooks registration
* move hooks registration after other LSMs
* add failsafes to check if a hook is not used by the kernel
* allow partial raw value access form the context (needed for programs
  generated by LLVM)

Changes since v3:
* split commit
* add hooks dealing with struct inode and struct path pointers:
  inode_permission and inode_getattr
* add abstraction over eBPF helper arguments thanks to wrapping structs
---
 include/linux/lsm_hooks.h|   5 +
 security/landlock/Makefile   |   7 +-
 security/landlock/common.h   |   2 +
 security/landlock/hooks.c|  83 ++
 security/landlock/hooks.h| 177 +
 security/landlock/hooks_fs.c | 586 +++
 security/landlock/hooks_fs.h |  19 ++
 security/landlock/init.c |  10 +
 security/security.c  |  12 +-
 9 files changed, 899 insertions(+), 2 deletions(-)
 create mode 100644 security/landlock/hooks.c
 create mode 100644 security/landlock/hooks.h
 create mode 100644 security/landlock/hooks_fs.c
 create mode 100644 security/landlock/hooks_fs.h

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 3a90febadbe2..7614c3d66265 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1982,5 +1982,10 @@ void __init loadpin_add_hooks(void);
 #else
 static inline void loadpin_add_hooks(void) { };
 #endif
+#ifdef CONFIG_SECURITY_LANDLOCK
+extern void __init landlock_add_hooks(void);
+#else
+static inline void __init landlock_add_hooks(void) { }
+#endif /* CONFIG_SECURITY_LANDLOCK */
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/security/landlock/Makefile b/security/landlock/Makefile
index 7205f9a7a2ee..b382be409b3b 100644
--- a/security/landlock/Makefile
+++ b/security/landlock/Makefile
@@ -1,3 +1,8 @@
+# Catch defined but unused hooks, e.g. error out if a HOOK_NEW_FS(foo) is not
+# used with a HOOK_INIT_FS(foo) in the struct security_hook_list
+# landlock_hooks.
+ccflags-$(CONFIG_SECURITY_LANDLOCK) += -Werror=unused-function
+
 obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o
 
-landlock-y := init.o
+landlock-y := init.o hooks.o hooks_fs.o
diff --git a/security/landlock/common.h b/security/landlock/common.h
index c82cbd3fb640..a69c35231d35 100644
--- a/security/landlock/common.h
+++ b/security/landlock/common.h
@@ -18,4 +18,6 @@
  */
 #define LANDLOCK_ABI 1
 
+#define LANDLOCK_NAME "landlock"
+
 #endif /* _SECURITY_LANDLOCK_COMMON_H */
diff --git a/security/landlock/hooks.c b/security/landlock/hooks.c
new file mode 100644
index ..b48caeb0a49a
--- /dev/null
+++ b/security/landlock/hooks.c
@@ -0,0 +1,83 @@
+/*
+ * Landlock LSM - hook helpers
+ *
+ * Copyright © 2016-2017 Mickaël Salaün <m...@digikod.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include  /* enum bpf_access_type, struct landlock_context */
+#include 
+#include  /* BPF_PROG_RUN() */
+#include  /* list_add_tail_rcu */
+#include  /* offsetof */
+
+#include "hooks.h" /* CTX_ARG_NB */
+
+
+bool landlock_is_valid_access(int off, int size, enum bpf_access_type type,
+   enum bpf_reg_type *reg_type,
+   enum bpf_re

[PATCH net-next v7 04/10] bpf: Define handle_fs and add a new helper bpf_handle_fs_get_mode()

2017-08-20 Thread Mickaël Salaün
Add an eBPF function bpf_handle_fs_get_mode(handle_fs) to get the mode
of a an abstract object wrapping either a file, a dentry, a path, or an
inode.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
Cc: Jann Horn <j...@thejh.net>
---

Changes since v6:
* remove WARN_ON() for missing dentry->d_inode
* refactor bpf_landlock_func_proto() (suggested by Kees Cook)

Changes since v5:
* cosmetic fixes and rebase

Changes since v4:
* use a file abstraction (handle) to wrap inode, dentry, path and file
  structs
* remove bpf_landlock_cmp_fs_beneath()
* rename the BPF helper and move it to kernel/bpf/
* tighten helpers accessible by a Landlock rule

Changes since v3:
* remove bpf_landlock_cmp_fs_prop() (suggested by Alexie Starovoitov)
* add hooks dealing with struct inode and struct path pointers:
  inode_permission and inode_getattr
* add abstraction over eBPF helper arguments thanks to wrapping structs
* add bpf_landlock_get_fs_mode() helper to check file type and mode
* merge WARN_ON() (suggested by Kees Cook)
* fix and update bpf_helpers.h
* use BPF_CALL_* for eBPF helpers (suggested by Alexie Starovoitov)
* make handle arraymap safe (RCU) and remove buggy synchronize_rcu()
* factor out the arraymay walk
* use size_t to index array (suggested by Jann Horn)

Changes since v2:
* add MNT_INTERNAL check to only add file handle from user-visible FS
  (e.g. no anonymous inode)
* replace struct file* with struct path* in map_landlock_handle
* add BPF protos
* fix bpf_landlock_cmp_fs_prop_with_struct_file()
---
 include/linux/bpf.h   | 31 ++
 include/uapi/linux/bpf.h  |  8 +
 kernel/bpf/Makefile   |  2 +-
 kernel/bpf/helpers_fs.c   | 52 +++
 kernel/bpf/verifier.c |  6 
 security/landlock/init.c  | 17 ++
 tools/include/uapi/linux/bpf.h| 10 +-
 tools/testing/selftests/bpf/bpf_helpers.h |  2 ++
 8 files changed, 126 insertions(+), 2 deletions(-)
 create mode 100644 kernel/bpf/helpers_fs.c

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index aef2e6f6d763..5316393150e1 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -16,6 +16,11 @@
 #include 
 #include 
 
+/* FS helpers */
+#include  /* struct dentry */
+#include  /* struct file, struct inode */
+#include  /* struct path */
+
 struct perf_event;
 struct bpf_prog;
 struct bpf_map;
@@ -85,6 +90,8 @@ enum bpf_arg_type {
 
ARG_PTR_TO_CTX, /* pointer to context */
ARG_ANYTHING,   /* any (initialized) argument is ok */
+
+   ARG_CONST_PTR_TO_HANDLE_FS, /* pointer to an abstract FS struct */
 };
 
 /* type of values returned from helper functions */
@@ -141,6 +148,7 @@ enum bpf_reg_type {
PTR_TO_STACK,/* reg == frame_pointer + offset */
PTR_TO_PACKET,   /* reg points to skb->data */
PTR_TO_PACKET_END,   /* skb->data + headlen */
+   CONST_PTR_TO_HANDLE_FS,  /* FS helpers */
 };
 
 /* The information passed from prog-specific *_is_valid_access
@@ -223,6 +231,26 @@ struct bpf_event_entry {
struct rcu_head rcu;
 };
 
+/* FS helpers */
+enum bpf_handle_fs_type {
+   BPF_HANDLE_FS_TYPE_NONE,
+   BPF_HANDLE_FS_TYPE_FILE,
+   BPF_HANDLE_FS_TYPE_INODE,
+   BPF_HANDLE_FS_TYPE_PATH,
+   BPF_HANDLE_FS_TYPE_DENTRY,
+};
+
+struct bpf_handle_fs {
+   enum bpf_handle_fs_type type;
+   union {
+   struct file *file;
+   struct inode *inode;
+   const struct path *path;
+   struct dentry *dentry;
+   };
+};
+
+
 u64 bpf_tail_call(u64 ctx, u64 r2, u64 index, u64 r4, u64 r5);
 u64 bpf_get_stackid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
 
@@ -415,6 +443,9 @@ extern const struct bpf_func_proto bpf_skb_vlan_pop_proto;
 extern const struct bpf_func_proto bpf_get_stackid_proto;
 extern const struct bpf_func_proto bpf_sock_map_update_proto;
 
+/* FS helpers */
+extern const struct bpf_func_proto bpf_handle_fs_get_mode_proto;
+
 /* Shared helpers among cBPF and eBPF. */
 void bpf_user_rnd_init_once(void);
 u64 bpf_user_rnd_u32(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 20da634da941..1624c0bbdf33 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -600,6 +600,13 @@ union bpf_attr {
  * @map_flags: sock map specific flags
  *bit 1: Enable strparser
  *other bits: reserved
+ *
+ * s64 bpf_handle_fs_get_mode(handle_fs)
+ * Get the mode of a struct bpf_handle_fs
+ * 

[PATCH net-next v7 06/10] seccomp,landlock: Handle Landlock events per process hierarchy

2017-08-20 Thread Mickaël Salaün
The seccomp(2) syscall can be used by a task to apply a Landlock rule to
itself. As a seccomp filter, a Landlock rule is enforced for the current
task and all its future children. A rule is immutable and a task can
only add new restricting rules to itself, forming a chain of rules.

A Landlock rule is tied to a Landlock event. If the action on a kernel
object is allowed by the other Linux security mechanisms (e.g. DAC,
capabilities, other LSM), then a Landlock event related to this kind of
object is triggered. The chain of rules for this event is then
evaluated. Each rule return a 32-bit value which can deny the action on
a kernel object with a non-zero value. If every rules of the chain
return zero, then the action on the object is allowed.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andrew Morton <a...@linux-foundation.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
Cc: Will Drewry <w...@chromium.org>
Link: https://lkml.kernel.org/r/c10a503d-5e35-7785-2f3d-25ed8dd63...@digikod.net
---

Changes since v6:
* rename some functions with more accurate names to reflect that an eBPF
  program for Landlock could be used for something else than a rule
* reword rule "appending" to "prepending" and explain it
* remove the superfluous no_new_privs check, only check global
  CAP_SYS_ADMIN when prepending a Landlock rule (needed for containers)
* create and use {get,put}_seccomp_landlock() (suggested by Kees Cook)
* replace ifdef with static inlined function (suggested by Kees Cook)
* use get_user() (suggested by Kees Cook)
* replace atomic_t with refcount_t (requested by Kees Cook)
* move struct landlock_{rule,events} from landlock.h to common.h
* cleanup headers

Changes since v5:
* remove struct landlock_node and use a similar inheritance mechanisme
  as seccomp-bpf (requested by Andy Lutomirski)
* rename SECCOMP_ADD_LANDLOCK_RULE to SECCOMP_APPEND_LANDLOCK_RULE
* rename file manager.c to providers.c
* add comments
* typo and cosmetic fixes

Changes since v4:
* merge manager and seccomp patches
* return -EFAULT in seccomp(2) when user_bpf_fd is null to easely check
  if Landlock is supported
* only allow a process with the global CAP_SYS_ADMIN to use Landlock
  (will be lifted in the future)
* add an early check to exit as soon as possible if the current process
  does not have Landlock rules

Changes since v3:
* remove the hard link with seccomp (suggested by Andy Lutomirski and
  Kees Cook):
  * remove the cookie which could imply multiple evaluation of Landlock
rules
  * remove the origin field in struct landlock_data
* remove documentation fix (merged upstream)
* rename the new seccomp command to SECCOMP_ADD_LANDLOCK_RULE
* internal renaming
* split commit
* new design to be able to inherit on the fly the parent rules

Changes since v2:
* Landlock programs can now be run without seccomp filter but for any
  syscall (from the process) or interruption
* move Landlock related functions and structs into security/landlock/*
  (to manage cgroups as well)
* fix seccomp filter handling: run Landlock programs for each of their
  legitimate seccomp filter
* properly clean up all seccomp results
* cosmetic changes to ease the understanding
* fix some ifdef
---
 include/linux/landlock.h  |  42 +++
 include/linux/seccomp.h   |   5 +
 include/uapi/linux/seccomp.h  |   1 +
 kernel/fork.c |   8 +-
 kernel/seccomp.c  |   3 +
 security/landlock/Makefile|   2 +-
 security/landlock/common.h|  42 +++
 security/landlock/hooks.c |  46 
 security/landlock/hooks.h |   5 +
 security/landlock/init.c  |   3 +-
 security/landlock/providers.c | 261 ++
 11 files changed, 415 insertions(+), 3 deletions(-)
 create mode 100644 include/linux/landlock.h
 create mode 100644 security/landlock/providers.c

diff --git a/include/linux/landlock.h b/include/linux/landlock.h
new file mode 100644
index ..c5c929931a1f
--- /dev/null
+++ b/include/linux/landlock.h
@@ -0,0 +1,42 @@
+/*
+ * Landlock LSM - public kernel headers
+ *
+ * Copyright © 2016-2017 Mickaël Salaün <m...@digikod.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _LINUX_LANDLOCK_H
+#define _LINUX_LANDLOCK_H
+
+#include 
+#include  /* task_struct */
+
+#ifdef CONFIG_SECURITY_LANDLOCK
+struct landlock_events;
+#endif /* CONFIG_SECURITY_LANDLOCK */
+
+#if defined(CONFIG_SECCOMP_FILTER) && defined(CONFIG_SECURITY_LANDLOCK)
+extern int landlock_seccomp_prepend_rule(unsigned int flags,
+   const char __user *user_bpf_fd);
+extern void put_s

[PATCH net-next v2 2/2] bpf: Extend check_uarg_tail_zero() checks

2017-08-07 Thread Mickaël Salaün
The function check_uarg_tail_zero() was created from bpf(2) for
BPF_OBJ_GET_INFO_BY_FD without taking the access_ok() nor the PAGE_SIZE
checks. Make this checks more generally available while unlikely to be
triggered, extend the memory range check and add an explanation
including why the ToCToU should not be a security concern.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Acked-by: Daniel Borkmann <dan...@iogearbox.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: David S. Miller <da...@davemloft.net>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Martin KaFai Lau <ka...@fb.com>
Link: 
https://lkml.kernel.org/r/CAGXu5j+vRGFvJZmjtAcT8Hi8B+Wz0e1b6VKYZHfQP_=dxzc...@mail.gmail.com
---
 kernel/bpf/syscall.c | 26 +++---
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index c653ee0bd162..fbe09a0cccf4 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -48,6 +48,15 @@ static const struct bpf_map_ops * const bpf_map_types[] = {
 #undef BPF_MAP_TYPE
 };
 
+/*
+ * If we're handed a bigger struct than we know of, ensure all the unknown bits
+ * are 0 - i.e. new user-space does not rely on any kernel feature extensions
+ * we don't know about yet.
+ *
+ * There is a ToCToU between this function call and the following
+ * copy_from_user() call. However, this is not a concern since this function is
+ * meant to be a future-proofing of bits.
+ */
 static int check_uarg_tail_zero(void __user *uaddr,
size_t expected_size,
size_t actual_size)
@@ -57,6 +66,12 @@ static int check_uarg_tail_zero(void __user *uaddr,
unsigned char val;
int err;
 
+   if (unlikely(actual_size > PAGE_SIZE))  /* silly large */
+   return -E2BIG;
+
+   if (unlikely(!access_ok(VERIFY_READ, uaddr, actual_size)))
+   return -EFAULT;
+
if (actual_size <= expected_size)
return 0;
 
@@ -1393,17 +1408,6 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, 
uattr, unsigned int, siz
if (!capable(CAP_SYS_ADMIN) && sysctl_unprivileged_bpf_disabled)
return -EPERM;
 
-   if (!access_ok(VERIFY_READ, uattr, 1))
-   return -EFAULT;
-
-   if (size > PAGE_SIZE)   /* silly large */
-   return -E2BIG;
-
-   /* If we're handed a bigger struct than we know of,
-* ensure all the unknown bits are 0 - i.e. new
-* user-space does not rely on any kernel feature
-* extensions we dont know about yet.
-*/
err = check_uarg_tail_zero(uattr, sizeof(attr), size);
if (err)
return err;
-- 
2.13.3



[PATCH net-next v2 1/2] bpf: Move check_uarg_tail_zero() upward

2017-08-07 Thread Mickaël Salaün
The function check_uarg_tail_zero() may be useful for other part of the
code in the syscall.c file. Move this function at the beginning of the
file.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Acked-by: Daniel Borkmann <dan...@iogearbox.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: David S. Miller <da...@davemloft.net>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Martin KaFai Lau <ka...@fb.com>
---

This is needed for the Landlock patch series. :)
---
 kernel/bpf/syscall.c | 52 ++--
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 6c772adabad2..c653ee0bd162 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -48,6 +48,32 @@ static const struct bpf_map_ops * const bpf_map_types[] = {
 #undef BPF_MAP_TYPE
 };
 
+static int check_uarg_tail_zero(void __user *uaddr,
+   size_t expected_size,
+   size_t actual_size)
+{
+   unsigned char __user *addr;
+   unsigned char __user *end;
+   unsigned char val;
+   int err;
+
+   if (actual_size <= expected_size)
+   return 0;
+
+   addr = uaddr + expected_size;
+   end  = uaddr + actual_size;
+
+   for (; addr < end; addr++) {
+   err = get_user(val, addr);
+   if (err)
+   return err;
+   if (val)
+   return -E2BIG;
+   }
+
+   return 0;
+}
+
 static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
 {
struct bpf_map *map;
@@ -1246,32 +1272,6 @@ static int bpf_map_get_fd_by_id(const union bpf_attr 
*attr)
return fd;
 }
 
-static int check_uarg_tail_zero(void __user *uaddr,
-   size_t expected_size,
-   size_t actual_size)
-{
-   unsigned char __user *addr;
-   unsigned char __user *end;
-   unsigned char val;
-   int err;
-
-   if (actual_size <= expected_size)
-   return 0;
-
-   addr = uaddr + expected_size;
-   end  = uaddr + actual_size;
-
-   for (; addr < end; addr++) {
-   err = get_user(val, addr);
-   if (err)
-   return err;
-   if (val)
-   return -E2BIG;
-   }
-
-   return 0;
-}
-
 static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
   const union bpf_attr *attr,
   union bpf_attr __user *uattr)
-- 
2.13.3



[PATCH net-next v1 1/2] bpf: Move check_uarg_tail_zero() upward

2017-08-07 Thread Mickaël Salaün
The function check_uarg_tail_zero() may be useful for other part of the
code in the syscall.c file. Move this function at the beginning of the
file.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Martin KaFai Lau <ka...@fb.com>
---

This is needed for the Landlock patch series. :)
---
 kernel/bpf/syscall.c | 52 ++--
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 6c772adabad2..c653ee0bd162 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -48,6 +48,32 @@ static const struct bpf_map_ops * const bpf_map_types[] = {
 #undef BPF_MAP_TYPE
 };
 
+static int check_uarg_tail_zero(void __user *uaddr,
+   size_t expected_size,
+   size_t actual_size)
+{
+   unsigned char __user *addr;
+   unsigned char __user *end;
+   unsigned char val;
+   int err;
+
+   if (actual_size <= expected_size)
+   return 0;
+
+   addr = uaddr + expected_size;
+   end  = uaddr + actual_size;
+
+   for (; addr < end; addr++) {
+   err = get_user(val, addr);
+   if (err)
+   return err;
+   if (val)
+   return -E2BIG;
+   }
+
+   return 0;
+}
+
 static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
 {
struct bpf_map *map;
@@ -1246,32 +1272,6 @@ static int bpf_map_get_fd_by_id(const union bpf_attr 
*attr)
return fd;
 }
 
-static int check_uarg_tail_zero(void __user *uaddr,
-   size_t expected_size,
-   size_t actual_size)
-{
-   unsigned char __user *addr;
-   unsigned char __user *end;
-   unsigned char val;
-   int err;
-
-   if (actual_size <= expected_size)
-   return 0;
-
-   addr = uaddr + expected_size;
-   end  = uaddr + actual_size;
-
-   for (; addr < end; addr++) {
-   err = get_user(val, addr);
-   if (err)
-   return err;
-   if (val)
-   return -E2BIG;
-   }
-
-   return 0;
-}
-
 static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
   const union bpf_attr *attr,
   union bpf_attr __user *uattr)
-- 
2.13.3



[PATCH net-next v1 2/2] bpf: Extend check_uarg_tail_zero() checks

2017-08-07 Thread Mickaël Salaün
The function check_uarg_tail_zero() was created from bpf(2) for
BPF_OBJ_GET_INFO_BY_FD without taking the access_ok() nor the PAGE_SIZE
checks. Make this checks more generally available while unlikely to be
triggered, extend the memory range check and add an explanation
including why the ToCToU should not be a security concern.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Martin KaFai Lau <ka...@fb.com>
Link: 
https://lkml.kernel.org/r/CAGXu5j+vRGFvJZmjtAcT8Hi8B+Wz0e1b6VKYZHfQP_=dxzc...@mail.gmail.com
---
 kernel/bpf/syscall.c | 26 +++---
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index c653ee0bd162..b884fdc371e0 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -48,6 +48,15 @@ static const struct bpf_map_ops * const bpf_map_types[] = {
 #undef BPF_MAP_TYPE
 };
 
+/*
+ * If we're handed a bigger struct than we know of, ensure all the unknown bits
+ * are 0 - i.e. new user-space does not rely on any kernel feature extensions
+ * we dont know about yet.
+ *
+ * There is a ToCToU between this function call and the following
+ * copy_from_user() call. However, this should not be a concern since this
+ * function is meant to be a future-proofing of bits.
+ */
 static int check_uarg_tail_zero(void __user *uaddr,
size_t expected_size,
size_t actual_size)
@@ -57,6 +66,12 @@ static int check_uarg_tail_zero(void __user *uaddr,
unsigned char val;
int err;
 
+   if (unlikely(!access_ok(VERIFY_READ, uaddr, actual_size)))
+   return -EFAULT;
+
+   if (unlikely(actual_size > PAGE_SIZE))  /* silly large */
+   return -E2BIG;
+
if (actual_size <= expected_size)
return 0;
 
@@ -1393,17 +1408,6 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, 
uattr, unsigned int, siz
if (!capable(CAP_SYS_ADMIN) && sysctl_unprivileged_bpf_disabled)
return -EPERM;
 
-   if (!access_ok(VERIFY_READ, uattr, 1))
-   return -EFAULT;
-
-   if (size > PAGE_SIZE)   /* silly large */
-   return -E2BIG;
-
-   /* If we're handed a bigger struct than we know of,
-* ensure all the unknown bits are 0 - i.e. new
-* user-space does not rely on any kernel feature
-* extensions we dont know about yet.
-*/
err = check_uarg_tail_zero(uattr, sizeof(attr), size);
if (err)
return err;
-- 
2.13.3



Re: [PATCH v1] samples/bpf: Add a .gitignore for binaries

2017-05-13 Thread Mickaël Salaün

On 13/02/2017 02:43, David Ahern wrote:
> On 2/12/17 2:23 PM, Mickaël Salaün wrote:
>> diff --git a/samples/bpf/.gitignore b/samples/bpf/.gitignore
>> new file mode 100644
>> index ..a7562a5ef4c2
>> --- /dev/null
>> +++ b/samples/bpf/.gitignore
>> @@ -0,0 +1,32 @@
>> +fds_example
>> +lathist
> 
> ...
> 
> Listing each target is going to be a PITA to maintain. It would be
> better to put targets into a build directory (bin?) and ignore the
> directory.
> 

It would require a lot of modifications to the Makefile and more
complexity. It seems much more simple for everyone to stick to a simple
gitignore file easily maintainable:
$ awk '$1 == "hostprogs-y" { print $3 }' < Makefile > .gitignore

Alexei, Daniel, what do you think about this? Do you want me to send a
v2 with the new tests?

 Mickaël



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v8 2/3] Add a eBPF helper function to retrieve socket uid

2017-04-20 Thread Mickaël Salaün

On 23/03/2017 01:27, Chenbo Feng wrote:
> From: Chenbo Feng 
> 
> Returns the owner uid of the socket inside a sk_buff. This is useful to
> perform per-UID accounting of network traffic or per-UID packet
> filtering. The socket need to be a fullsock otherwise overflowuid is
> returned.
> 
> Signed-off-by: Chenbo Feng 
> ---
>  include/uapi/linux/bpf.h   |  9 -
>  net/core/filter.c  | 22 ++
>  tools/include/uapi/linux/bpf.h |  3 ++-
>  3 files changed, 32 insertions(+), 2 deletions(-)
> 
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index dc81a9f..ff42111 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -462,6 +462,12 @@ union bpf_attr {
>   * @skb: pointer to skb
>   * Return: 8 Bytes non-decreasing number on success or 0 if the socket
>   * field is missing inside sk_buff
> + *
> + * u32 bpf_get_socket_uid(skb)
> + * Get the owner uid of the socket stored inside sk_buff.
> + * @skb: pointer to skb
> + * Return: uid of the socket owner on success or 0 if the socket pointer
> + * inside sk_buff is NULL

What about UID 0? Why not returning -1 on error?

>   */
>  #define __BPF_FUNC_MAPPER(FN)\
>   FN(unspec), \
> @@ -510,7 +516,8 @@ union bpf_attr {
>   FN(skb_change_head),\
>   FN(xdp_adjust_head),\
>   FN(probe_read_str), \
> - FN(get_socket_cookie),
> + FN(get_socket_cookie),  \
> + FN(get_socket_uid),
>  
>  /* integer value in 'imm' field of BPF_CALL instruction selects which helper
>   * function eBPF program intends to call
> diff --git a/net/core/filter.c b/net/core/filter.c
> index 5b65ae3..93cc4af 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -2612,6 +2612,24 @@ static const struct bpf_func_proto 
> bpf_get_socket_cookie_proto = {
>   .arg1_type  = ARG_PTR_TO_CTX,
>  };
>  
> +BPF_CALL_1(bpf_get_socket_uid, struct sk_buff *, skb)
> +{
> + struct sock *sk = sk_to_full_sk(skb->sk);
> + kuid_t kuid;
> +
> + if (!sk || !sk_fullsock(sk))
> + return overflowuid;
> + kuid = sock_net_uid(sock_net(sk), sk);
> + return from_kuid_munged(sock_net(sk)->user_ns, kuid);
> +}
> +
> +static const struct bpf_func_proto bpf_get_socket_uid_proto = {
> + .func   = bpf_get_socket_uid,
> + .gpl_only   = false,
> + .ret_type   = RET_INTEGER,
> + .arg1_type  = ARG_PTR_TO_CTX,
> +};
> +
>  static const struct bpf_func_proto *
>  bpf_base_func_proto(enum bpf_func_id func_id)
>  {
> @@ -2648,6 +2666,8 @@ sk_filter_func_proto(enum bpf_func_id func_id)
>   return _skb_load_bytes_proto;
>   case BPF_FUNC_get_socket_cookie:
>   return _get_socket_cookie_proto;
> + case BPF_FUNC_get_socket_uid:
> + return _get_socket_uid_proto;
>   default:
>   return bpf_base_func_proto(func_id);
>   }
> @@ -2709,6 +2729,8 @@ tc_cls_act_func_proto(enum bpf_func_id func_id)
>   return _skb_under_cgroup_proto;
>   case BPF_FUNC_get_socket_cookie:
>   return _get_socket_cookie_proto;
> + case BPF_FUNC_get_socket_uid:
> + return _get_socket_uid_proto;
>   default:
>   return bpf_base_func_proto(func_id);
>   }
> diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
> index a94bdd3..4a2d56d 100644
> --- a/tools/include/uapi/linux/bpf.h
> +++ b/tools/include/uapi/linux/bpf.h
> @@ -504,7 +504,8 @@ union bpf_attr {
>   FN(skb_change_head),\
>   FN(xdp_adjust_head),\
>   FN(probe_read_str), \
> - FN(get_socket_cookie),
> + FN(get_socket_cookie),  \
> + FN(get_socket_uid),
>  
>  /* integer value in 'imm' field of BPF_CALL instruction selects which helper
>   * function eBPF program intends to call
> 



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v6 05/11] seccomp: Split put_seccomp_filter() with put_seccomp()

2017-04-19 Thread Mickaël Salaün

On 19/04/2017 00:47, Mickaël Salaün wrote:
> 
> On 19/04/2017 00:23, Kees Cook wrote:
>> On Tue, Mar 28, 2017 at 4:46 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>> The semantic is unchanged. This will be useful for the Landlock
>>> integration with seccomp (next commit).
>>>
>>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>>> Cc: Kees Cook <keesc...@chromium.org>
>>> Cc: Andy Lutomirski <l...@amacapital.net>
>>> Cc: Will Drewry <w...@chromium.org>
>>> ---
>>>  include/linux/seccomp.h |  4 ++--
>>>  kernel/fork.c   |  2 +-
>>>  kernel/seccomp.c| 18 +-
>>>  3 files changed, 16 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
>>> index ecc296c137cd..e25aee2cdfc0 100644
>>> --- a/include/linux/seccomp.h
>>> +++ b/include/linux/seccomp.h
>>> @@ -77,10 +77,10 @@ static inline int seccomp_mode(struct seccomp *s)
>>>  #endif /* CONFIG_SECCOMP */
>>>
>>>  #ifdef CONFIG_SECCOMP_FILTER
>>> -extern void put_seccomp_filter(struct task_struct *tsk);
>>> +extern void put_seccomp(struct task_struct *tsk);
>>>  extern void get_seccomp_filter(struct task_struct *tsk);
>>>  #else  /* CONFIG_SECCOMP_FILTER */
>>> -static inline void put_seccomp_filter(struct task_struct *tsk)
>>> +static inline void put_seccomp(struct task_struct *tsk)
>>>  {
>>> return;
>>>  }
>>> diff --git a/kernel/fork.c b/kernel/fork.c
>>> index 6c463c80e93d..a27d8e67ce33 100644
>>> --- a/kernel/fork.c
>>> +++ b/kernel/fork.c
>>> @@ -363,7 +363,7 @@ void free_task(struct task_struct *tsk)
>>>  #endif
>>> rt_mutex_debug_task_free(tsk);
>>> ftrace_graph_exit_task(tsk);
>>> -   put_seccomp_filter(tsk);
>>> +   put_seccomp(tsk);
>>> arch_release_task_struct(tsk);
>>> if (tsk->flags & PF_KTHREAD)
>>> free_kthread_struct(tsk);
>>> diff --git a/kernel/seccomp.c b/kernel/seccomp.c
>>> index 65f61077ad50..326f79e32127 100644
>>> --- a/kernel/seccomp.c
>>> +++ b/kernel/seccomp.c
>>> @@ -64,6 +64,8 @@ struct seccomp_filter {
>>>  /* Limit any path through the tree to 256KB worth of instructions. */
>>>  #define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
>>>
>>> +static void put_seccomp_filter(struct seccomp_filter *filter);
>>
>> Can this be reorganized easily to avoid a forward-declaration?
> 
> I didn't want to move too much code but I will.
> 
>>
>>> +
>>>  /*
>>>   * Endianness is explicitly ignored and left for BPF program authors to 
>>> manage
>>>   * as per the specific architecture.
>>> @@ -314,7 +316,7 @@ static inline void seccomp_sync_threads(void)
>>>  * current's path will hold a reference.  (This also
>>>  * allows a put before the assignment.)
>>>  */
>>> -   put_seccomp_filter(thread);
>>> +   put_seccomp_filter(thread->seccomp.filter);
>>> smp_store_release(>seccomp.filter,
>>>   caller->seccomp.filter);
>>>
>>> @@ -476,10 +478,11 @@ static inline void seccomp_filter_free(struct 
>>> seccomp_filter *filter)
>>> }
>>>  }
>>>
>>> -/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */
>>> -void put_seccomp_filter(struct task_struct *tsk)
>>> +/* put_seccomp_filter - decrements the ref count of a filter */
>>> +static void put_seccomp_filter(struct seccomp_filter *filter)
>>>  {
>>> -   struct seccomp_filter *orig = tsk->seccomp.filter;
>>> +   struct seccomp_filter *orig = filter;
>>> +
>>> /* Clean up single-reference branches iteratively. */
>>> while (orig && atomic_dec_and_test(>usage)) {
>>> struct seccomp_filter *freeme = orig;
>>> @@ -488,6 +491,11 @@ void put_seccomp_filter(struct task_struct *tsk)
>>> }
>>>  }
>>>
>>> +void put_seccomp(struct task_struct *tsk)
>>> +{
>>> +   put_seccomp_filter(tsk->seccomp.filter);
>>> +}
>>> +
>>>  static void seccomp_init_siginfo(siginfo_t *info, int syscall, int reason)
>>>  {
>>> memset(info, 0, sizeof(*info));
>>> @@ -914,7 +922,7 @@ long seccomp_get_filter(struct task_struct *task, 
>>> unsigned long filter_off,
>>> if (copy_to_user(data, fprog->filter, bpf_classic_proglen(fprog)))
>>> ret = -EFAULT;
>>>
>>> -   put_seccomp_filter(task);
>>> +   put_seccomp_filter(task->seccomp.filter);
>>> return ret;
>>
>> I don't like that the arguments to get_seccomp_filter() and
>> put_seccomp_filter() are now different. I think they should match for
>> readability.
> 
> OK, I can do that.
> 

Kees, can I send this as a separate patch?



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v6 09/11] seccomp: Enhance test_harness with an assert step mechanism

2017-04-19 Thread Mickaël Salaün


On 20/04/2017 00:02, Kees Cook wrote:
> On Wed, Apr 19, 2017 at 2:51 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>
>> On 19/04/2017 02:02, Kees Cook wrote:
>>> On Tue, Mar 28, 2017 at 4:46 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>>> This is useful to return an information about the error without being
>>>> able to write to TH_LOG_STREAM.
>>>>
>>>> Helpers from test_harness.h may be useful outside of the seccomp
>>>> directory.
>>>>
>>>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>>>> Cc: Andy Lutomirski <l...@amacapital.net>
>>>> Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
>>>> Cc: Kees Cook <keesc...@chromium.org>
>>>> Cc: Shuah Khan <sh...@kernel.org>
>>>> Cc: Will Drewry <w...@chromium.org>
>>>> ---
>>>>  tools/testing/selftests/seccomp/test_harness.h | 8 +++-
>>>>  1 file changed, 7 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/tools/testing/selftests/seccomp/test_harness.h 
>>>> b/tools/testing/selftests/seccomp/test_harness.h
>>>> index a786c69c7584..77e407663e06 100644
>>>> --- a/tools/testing/selftests/seccomp/test_harness.h
>>>> +++ b/tools/testing/selftests/seccomp/test_harness.h
>>>> @@ -397,7 +397,7 @@ struct __test_metadata {
>>>> const char *name;
>>>> void (*fn)(struct __test_metadata *);
>>>> int termsig;
>>>> -   int passed;
>>>> +   __s8 passed;
>>>
>>> Why the reduction here? int is signed too?
>>
>> Because the return code of a process is capped to 8 bits and I use a
>> negative value to not mess with the current interpretation of 0 (error)
>> and 1 (OK) for the "passed" variable.
>>
>>>
>>>> int trigger; /* extra handler after the evaluation */
>>>> struct __test_metadata *prev, *next;
>>>>  };
>>>> @@ -476,6 +476,12 @@ void __run_test(struct __test_metadata *t)
>>>> "instead of by signal (code: 
>>>> %d)\n",
>>>> t->name,
>>>> WEXITSTATUS(status));
>>>> +   } else if (t->passed < 0) {
>>>> +   fprintf(TH_LOG_STREAM,
>>>> +   "%s: Failed at step #%d\n",
>>>> +   t->name,
>>>> +   t->passed * -1);
>>>> +   t->passed = 0;
>>>> }
>>>
>>> Instead of creating an overloaded mechanism here, perhaps have an
>>> option reporting mechanism that can be enabled. Like adding to
>>> __test_metadata "bool no_stream; int test_number;" and adding
>>> test_number++ to each ASSERT/EXCEPT call, and doing something like:
>>>
>>> if (t->no_stream) {
>>>   fprintf(TH_LOG_STREAM,
>>>   "%s: Failed at step #%d\n",
>>>   t->name,
>>>t->test_number);
>>> }
>>>
>>> It'd be a cleaner approach, maybe?
>>
>> Good idea, we will then be able to use 255 steps!
>>
>> Do you want me to send this as a separate patch?
>>
>> Can we move test_harness.h outside of the seccomp directory to be
>> available to other subsystems as well?
> 
> Yeah, I would do two patches, and send them out separately (to shuah
> with lkml and me in cc at least), one to move test_hardness.h into
> some include/ directory, and then to add the new logic for streamless
> reporting.
> 
> Thanks!
> 
> -Kees
> 
> 

Good, in which place and name would it fit better?



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v6 04/11] landlock: Add LSM hooks related to filesystem

2017-04-19 Thread Mickaël Salaün

On 19/04/2017 01:40, Kees Cook wrote:
> On Tue, Apr 18, 2017 at 4:16 PM, Casey Schaufler <ca...@schaufler-ca.com> 
> wrote:
>> On 4/18/2017 3:44 PM, Mickaël Salaün wrote:
>>> On 19/04/2017 00:17, Kees Cook wrote:
>>>> On Tue, Mar 28, 2017 at 4:46 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>>>> +void __init landlock_add_hooks(void)
>>>>> +{
>>>>> +   pr_info("landlock: Version %u", LANDLOCK_VERSION);
>>>>> +   landlock_add_hooks_fs();
>>>>> +   security_add_hooks(NULL, 0, "landlock");
>>>>> +   bpf_register_prog_type(_landlock_type);
>>>> I'm confused by the separation of hook registration here. The call to
>>>> security_add_hooks is with count=0 is especially weird. Why isn't this
>>>> just a single call with security_add_hooks(landlock_hooks,
>>>> ARRAY_SIZE(landlock_hooks), "landlock")?
>>> Yes, this is ugly with the new security_add_hooks() with three arguments
>>> but I wanted to split the hooks definition in multiple files.
>>
>> Why? I'll buy a good argument, but there are dangers in
>> allowing multiple calls to security_add_hooks().

I prefer to have one file per hook "family" (e.g. filesystem, network,
ptrace…). This reduce the mess with all the included files (needed for
LSM hook argument types) and make the files easier to read, understand
and maintain.

>>
>>>
>>> The current security_add_hooks() use lsm_append(lsm, _names) which
>>> is not exported. Unfortunately, calling multiple security_add_hooks()
>>> with the same LSM name would register multiple names for the same LSM…
>>> Is it OK if I modify this function to not add duplicated entries?
>>
>> It may seem absurd, but it's conceivable that a module might
>> have two hooks it wants called. My example is a module that
>> counts the number of times SELinux denies a process access to
>> things (which needs to be called before and after SELinux in
>> order to detect denials) and takes "appropriate action" if
>> too many denials occur. It would be weird, wonky and hackish,
>> but that never stopped anybody before.

Right, but now, with the new lsm_append(), module names are concatenated
("%s,%s") in the lsm_names variable. It would be nice to not pollute
this string with multiple time the same module name.

> 
> If ends up being sane and clear, I'm fine with allowing multiple calls.
> 
> -Kees
> 



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v6 09/11] seccomp: Enhance test_harness with an assert step mechanism

2017-04-19 Thread Mickaël Salaün

On 19/04/2017 02:02, Kees Cook wrote:
> On Tue, Mar 28, 2017 at 4:46 PM, Mickaël Salaün <m...@digikod.net> wrote:
>> This is useful to return an information about the error without being
>> able to write to TH_LOG_STREAM.
>>
>> Helpers from test_harness.h may be useful outside of the seccomp
>> directory.
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>> Cc: Andy Lutomirski <l...@amacapital.net>
>> Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
>> Cc: Kees Cook <keesc...@chromium.org>
>> Cc: Shuah Khan <sh...@kernel.org>
>> Cc: Will Drewry <w...@chromium.org>
>> ---
>>  tools/testing/selftests/seccomp/test_harness.h | 8 +++-
>>  1 file changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/testing/selftests/seccomp/test_harness.h 
>> b/tools/testing/selftests/seccomp/test_harness.h
>> index a786c69c7584..77e407663e06 100644
>> --- a/tools/testing/selftests/seccomp/test_harness.h
>> +++ b/tools/testing/selftests/seccomp/test_harness.h
>> @@ -397,7 +397,7 @@ struct __test_metadata {
>> const char *name;
>> void (*fn)(struct __test_metadata *);
>> int termsig;
>> -   int passed;
>> +   __s8 passed;
> 
> Why the reduction here? int is signed too?

Because the return code of a process is capped to 8 bits and I use a
negative value to not mess with the current interpretation of 0 (error)
and 1 (OK) for the "passed" variable.

> 
>> int trigger; /* extra handler after the evaluation */
>> struct __test_metadata *prev, *next;
>>  };
>> @@ -476,6 +476,12 @@ void __run_test(struct __test_metadata *t)
>> "instead of by signal (code: %d)\n",
>> t->name,
>> WEXITSTATUS(status));
>> +   } else if (t->passed < 0) {
>> +   fprintf(TH_LOG_STREAM,
>> +   "%s: Failed at step #%d\n",
>> +   t->name,
>> +   t->passed * -1);
>> +   t->passed = 0;
>> }
> 
> Instead of creating an overloaded mechanism here, perhaps have an
> option reporting mechanism that can be enabled. Like adding to
> __test_metadata "bool no_stream; int test_number;" and adding
> test_number++ to each ASSERT/EXCEPT call, and doing something like:
> 
> if (t->no_stream) {
>   fprintf(TH_LOG_STREAM,
>   "%s: Failed at step #%d\n",
>   t->name,
>t->test_number);
> }
> 
> It'd be a cleaner approach, maybe?

Good idea, we will then be able to use 255 steps!

Do you want me to send this as a separate patch?

Can we move test_harness.h outside of the seccomp directory to be
available to other subsystems as well?



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v6 00/11] Landlock LSM: Toward unprivileged sandboxing

2017-04-18 Thread Mickaël Salaün

On 19/04/2017 01:26, Kees Cook wrote:
> On Tue, Mar 28, 2017 at 4:46 PM, Mickaël Salaün <m...@digikod.net> wrote:
>> This sixth series add some changes to the previous one [1], including a 
>> simpler
>> rule inheritance hierarchy (similar to seccomp-bpf), a ptrace scope 
>> protection,
>> some file renaming (better feature identification per file), a future-proof
>> eBPF subtype and miscellaneous cosmetic fixes.
> 
> Sorry for the delay in review! I finally had a chunk of time I could
> devote to this. I really like how it's heading. I still wonder about
> its overlap with seccomp (it's really only using the syscall now...),
> but that's just a detail. Getting the abstraction away from direct LSM
> hooks looks good.
> 
>> There is as yet no way to allow a process to access only a subset of the
>> filesystem where the subset is specified via a path or a file descriptor.  
>> This
>> feature is intentionally left out so as to minimize the amount of code of 
>> this
>> patch series but will come in a following series.  However, it is possible to
>> check the file type, as done in the following example.
> 
> I understand why you've taken a progressive approach here, but I think
> there are two fundamental areas where people will use Landlock: path
> evaluation and network address evaluation. I think it's worth
> expanding this series to include those two confinement examples, since
> that can help people understand what the "general" case will look
> like.

I agree that it would be more useful to add a path/FS evaluation,
however we agreed at LPC that it would be another patch series:
https://lkml.kernel.org/r/5828776a.1010...@digikod.net
It brings more complexity and a new kind of BPF map, which should be
reviewed in a separate series.

> 
> As I mentioned in one of the patch review emails, I think there needs
> to be a clearer explanation of how usage counting works vs the
> "events" (which I think of as "rule tables" not events -- maybe it
> needs a new name?) and "rule" lists. I think I understand it, but I
> spent a lot of time trying to get there. More comments would help.

I though about different names and the previous one was PDP (for Policy
Decision Point) which is used in the literature, but "event" seems
easier to understand and close enough with "hook". Rule tables doesn't
seems to express what is the meaning to register an event/hook.

I'll add more comments to explain how it works.

> 
> Finally, another thing I'm curious about is how to deal with the
> thread-sync issue. Seccomp uses its TSYNC thing, and I'd expect we'd
> want something similar for landlock... but that looks really hairy as
> far as locking goes. Perhaps it's already solved by using the same
> locking seccomp uses, in which case I'm less inclined to kick landlock
> out of seccomp.c. :)

I didn't work on it but it should be really similar to seccomp-bpf.

> 
> Looks like it's coming along nicely! Thanks for continuing to work on this!
> 
> -Kees
> 



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v6 10/11] bpf,landlock: Add tests for Landlock

2017-04-18 Thread Mickaël Salaün

On 19/04/2017 01:16, Kees Cook wrote:
> On Tue, Mar 28, 2017 at 4:46 PM, Mickaël Salaün <m...@digikod.net> wrote:
>> Test basic context access, ptrace protection and filesystem event with
>> multiple cases.
>>
>> Changes since v5:
>> * add subtype test
>> * add ptrace tests
>> * split and rename files
>> * cleanup and rebase
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>> Cc: Alexei Starovoitov <a...@kernel.org>
>> Cc: Andy Lutomirski <l...@amacapital.net>
>> Cc: Daniel Borkmann <dan...@iogearbox.net>
>> Cc: David S. Miller <da...@davemloft.net>
>> Cc: James Morris <james.l.mor...@oracle.com>
>> Cc: Kees Cook <keesc...@chromium.org>
>> Cc: Serge E. Hallyn <se...@hallyn.com>
>> Cc: Shuah Khan <sh...@kernel.org>
>> Cc: Will Drewry <w...@chromium.org>
>> ---
>>  tools/testing/selftests/Makefile   |   1 +
>>  tools/testing/selftests/bpf/test_verifier.c|  64 +
>>  tools/testing/selftests/landlock/.gitignore|   4 +
>>  tools/testing/selftests/landlock/Makefile  |  47 
>>  tools/testing/selftests/landlock/rules/Makefile|  52 
>>  tools/testing/selftests/landlock/rules/README.rst  |   1 +
>>  .../testing/selftests/landlock/rules/bpf_helpers.h |   1 +
>>  .../testing/selftests/landlock/rules/fs_no_open.c  |  31 +++
>>  .../selftests/landlock/rules/fs_read_only.c|  31 +++
>>  tools/testing/selftests/landlock/test.h|  35 +++
>>  tools/testing/selftests/landlock/test_base.c   |  31 +++
>>  tools/testing/selftests/landlock/test_fs.c | 305 
>> +
>>  tools/testing/selftests/landlock/test_ptrace.c | 161 +++
>>  13 files changed, 764 insertions(+)
>>  create mode 100644 tools/testing/selftests/landlock/.gitignore
>>  create mode 100644 tools/testing/selftests/landlock/Makefile
>>  create mode 100644 tools/testing/selftests/landlock/rules/Makefile
>>  create mode 12 tools/testing/selftests/landlock/rules/README.rst
>>  create mode 12 tools/testing/selftests/landlock/rules/bpf_helpers.h
>>  create mode 100644 tools/testing/selftests/landlock/rules/fs_no_open.c
>>  create mode 100644 tools/testing/selftests/landlock/rules/fs_read_only.c
>>  create mode 100644 tools/testing/selftests/landlock/test.h
>>  create mode 100644 tools/testing/selftests/landlock/test_base.c
>>  create mode 100644 tools/testing/selftests/landlock/test_fs.c
>>  create mode 100644 tools/testing/selftests/landlock/test_ptrace.c
>>
>> diff --git a/tools/testing/selftests/Makefile 
>> b/tools/testing/selftests/Makefile
>> index d8593f1251ec..b584ad456428 100644
>> --- a/tools/testing/selftests/Makefile
>> +++ b/tools/testing/selftests/Makefile
>> @@ -12,6 +12,7 @@ TARGETS += gpio
>>  TARGETS += intel_pstate
>>  TARGETS += ipc
>>  TARGETS += kcmp
>> +TARGETS += landlock
>>  TARGETS += lib
>>  TARGETS += membarrier
>>  TARGETS += memfd
>> diff --git a/tools/testing/selftests/bpf/test_verifier.c 
>> b/tools/testing/selftests/bpf/test_verifier.c
>> index daa87dd7c80e..77255b14871e 100644
>> --- a/tools/testing/selftests/bpf/test_verifier.c
>> +++ b/tools/testing/selftests/bpf/test_verifier.c
>> @@ -4536,6 +4536,70 @@ static struct bpf_test tests[] = {
>> .result = REJECT,
>> .has_prog_subtype = true,
>> },
>> +   {
>> +   "missing subtype",
>> +   .insns = {
>> +   BPF_MOV32_IMM(BPF_REG_0, 0),
>> +   BPF_EXIT_INSN(),
>> +   },
>> +   .errstr = "",
>> +   .result = REJECT,
>> +   .prog_type = BPF_PROG_TYPE_LANDLOCK,
>> +   },
>> +   {
>> +   "landlock/fs: always accept",
>> +   .insns = {
>> +   BPF_MOV32_IMM(BPF_REG_0, 0),
>> +   BPF_EXIT_INSN(),
>> +   },
>> +   .result = ACCEPT,
>> +   .prog_type = BPF_PROG_TYPE_LANDLOCK,
>> +   .has_prog_subtype = true,
>> +   .prog_subtype = {
>> +   .landlock_rule = {
>> +   .version = 1,
>> +   .event = LANDLOCK_SUBTYPE_EVENT_FS,
>> +   }
>> +   },
>> +   },
>> +   {
>> + 

Re: [PATCH net-next v6 08/11] bpf: Add a Landlock sandbox example

2017-04-18 Thread Mickaël Salaün

On 19/04/2017 01:06, Kees Cook wrote:
> On Tue, Mar 28, 2017 at 4:46 PM, Mickaël Salaün <m...@digikod.net> wrote:
>> Add a basic sandbox tool to create a process isolated from some part of
>> the system. This sandbox create a read-only environment. It is only
>> allowed to write to a character device such as a TTY:
>>
>>   # :> X
>>   # echo $?
>>   0
>>   # ./samples/bpf/landlock1 /bin/sh -i
>>   Launching a new sandboxed process.
>>   # :> Y
>>   cannot create Y: Operation not permitted
>>
>> Changes since v5:
>> * cosmetic fixes
>> * rebase
>>
>> Changes since v4:
>> * write Landlock rule in C and compiled it with LLVM
>> * remove cgroup handling
>> * remove path handling: only handle a read-only environment
>> * remove errno return codes
>>
>> Changes since v3:
>> * remove seccomp and origin field: completely free from seccomp programs
>> * handle more FS-related hooks
>> * handle inode hooks and directory traversal
>> * add faked but consistent view thanks to ENOENT
>> * add /lib64 in the example
>> * fix spelling
>> * rename some types and definitions (e.g. SECCOMP_ADD_LANDLOCK_RULE)
>>
>> Changes since v2:
>> * use BPF_PROG_ATTACH for cgroup handling
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>> Cc: Alexei Starovoitov <a...@kernel.org>
>> Cc: Andy Lutomirski <l...@amacapital.net>
>> Cc: Daniel Borkmann <dan...@iogearbox.net>
>> Cc: David S. Miller <da...@davemloft.net>
>> Cc: James Morris <james.l.mor...@oracle.com>
>> Cc: Kees Cook <keesc...@chromium.org>
>> Cc: Serge E. Hallyn <se...@hallyn.com>
>> ---
>>  samples/bpf/Makefile |   4 ++
>>  samples/bpf/bpf_load.c   |  31 +++--
>>  samples/bpf/landlock1_kern.c |  46 +++
>>  samples/bpf/landlock1_user.c | 102 
>> +++
>>  4 files changed, 179 insertions(+), 4 deletions(-)
>>  create mode 100644 samples/bpf/landlock1_kern.c
>>  create mode 100644 samples/bpf/landlock1_user.c
>>
>> diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
>> index d42b495b0992..4743674a3fa3 100644
>> --- a/samples/bpf/Makefile
>> +++ b/samples/bpf/Makefile
>> @@ -36,6 +36,7 @@ hostprogs-y += lwt_len_hist
>>  hostprogs-y += xdp_tx_iptunnel
>>  hostprogs-y += test_map_in_map
>>  hostprogs-y += per_socket_stats_example
>> +hostprogs-y += landlock1
>>
>>  # Libbpf dependencies
>>  LIBBPF := ../../tools/lib/bpf/bpf.o
>> @@ -76,6 +77,7 @@ lwt_len_hist-objs := bpf_load.o $(LIBBPF) 
>> lwt_len_hist_user.o
>>  xdp_tx_iptunnel-objs := bpf_load.o $(LIBBPF) xdp_tx_iptunnel_user.o
>>  test_map_in_map-objs := bpf_load.o $(LIBBPF) test_map_in_map_user.o
>>  per_socket_stats_example-objs := $(LIBBPF) cookie_uid_helper_example.o
>> +landlock1-objs := bpf_load.o $(LIBBPF) landlock1_user.o
>>
>>  # Tell kbuild to always build the programs
>>  always := $(hostprogs-y)
>> @@ -111,6 +113,7 @@ always += lwt_len_hist_kern.o
>>  always += xdp_tx_iptunnel_kern.o
>>  always += test_map_in_map_kern.o
>>  always += cookie_uid_helper_example.o
>> +always += landlock1_kern.o
>>
>>  HOSTCFLAGS += -I$(objtree)/usr/include
>>  HOSTCFLAGS += -I$(srctree)/tools/lib/
>> @@ -146,6 +149,7 @@ HOSTLOADLIBES_tc_l2_redirect += -l elf
>>  HOSTLOADLIBES_lwt_len_hist += -l elf
>>  HOSTLOADLIBES_xdp_tx_iptunnel += -lelf
>>  HOSTLOADLIBES_test_map_in_map += -lelf
>> +HOSTLOADLIBES_landlock1 += -lelf
>>
>>  # Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on 
>> cmdline:
>>  #  make samples/bpf/ LLC=~/git/llvm/build/bin/llc 
>> CLANG=~/git/llvm/build/bin/clang
>> diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
>> index 4a3460d7c01f..3713e5e2e998 100644
>> --- a/samples/bpf/bpf_load.c
>> +++ b/samples/bpf/bpf_load.c
>> @@ -29,6 +29,8 @@
>>
>>  static char license[128];
>>  static int kern_version;
>> +static union bpf_prog_subtype subtype = {};
>> +static bool has_subtype;
>>  static bool processed_sec[128];
>>  char bpf_log_buf[BPF_LOG_BUF_SIZE];
>>  int map_fd[MAX_MAPS];
>> @@ -68,6 +70,7 @@ static int load_and_attach(const char *event, struct 
>> bpf_insn *prog, int size)
>> bool is_perf_event = strncmp(event, "perf_event", 10) == 0;
>> bool is_cgroup_skb = strncmp(event, "cgroup/skb", 10) == 0;
>> bool is_cgroup_sk = strncmp(event, &qu

Re: [PATCH net-next v6 06/11] seccomp,landlock: Handle Landlock events per process hierarchy

2017-04-18 Thread Mickaël Salaün


On 19/04/2017 00:53, Kees Cook wrote:
> On Tue, Mar 28, 2017 at 4:46 PM, Mickaël Salaün <m...@digikod.net> wrote:
>> The seccomp(2) syscall can be used by a task to apply a Landlock rule to
>> itself. As a seccomp filter, a Landlock rule is enforced for the current
>> task and all its future children. A rule is immutable and a task can
>> only add new restricting rules to itself, forming a chain of rules.
>>
>> A Landlock rule is tied to a Landlock event. If the use of a kernel
>> object is allowed by the other Linux security mechanisms (e.g. DAC,
>> capabilities, other LSM), then a Landlock event related to this kind of
>> object is triggered. The chain of rules for this event is then
>> evaluated. Each rule return a 32-bit value which can deny the use of a
>> kernel object with a non-zero value. If every rules of the chain return
>> zero, then the use of the object is allowed.
>>
>> Changes since v5:
>> * remove struct landlock_node and use a similar inheritance mechanisme
>>   as seccomp-bpf (requested by Andy Lutomirski)
>> * rename SECCOMP_ADD_LANDLOCK_RULE to SECCOMP_APPEND_LANDLOCK_RULE
>> * rename file manager.c to providers.c
>> * add comments
>> * typo and cosmetic fixes
>>
>> Changes since v4:
>> * merge manager and seccomp patches
>> * return -EFAULT in seccomp(2) when user_bpf_fd is null to easely check
>>   if Landlock is supported
>> * only allow a process with the global CAP_SYS_ADMIN to use Landlock
>>   (will be lifted in the future)
>> * add an early check to exit as soon as possible if the current process
>>   does not have Landlock rules
>>
>> Changes since v3:
>> * remove the hard link with seccomp (suggested by Andy Lutomirski and
>>   Kees Cook):
>>   * remove the cookie which could imply multiple evaluation of Landlock
>> rules
>>   * remove the origin field in struct landlock_data
>> * remove documentation fix (merged upstream)
>> * rename the new seccomp command to SECCOMP_ADD_LANDLOCK_RULE
>> * internal renaming
>> * split commit
>> * new design to be able to inherit on the fly the parent rules
>>
>> Changes since v2:
>> * Landlock programs can now be run without seccomp filter but for any
>>   syscall (from the process) or interruption
>> * move Landlock related functions and structs into security/landlock/*
>>   (to manage cgroups as well)
>> * fix seccomp filter handling: run Landlock programs for each of their
>>   legitimate seccomp filter
>> * properly clean up all seccomp results
>> * cosmetic changes to ease the understanding
>> * fix some ifdef
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>> Cc: Alexei Starovoitov <a...@kernel.org>
>> Cc: Andrew Morton <a...@linux-foundation.org>
>> Cc: Andy Lutomirski <l...@amacapital.net>
>> Cc: James Morris <james.l.mor...@oracle.com>
>> Cc: Kees Cook <keesc...@chromium.org>
>> Cc: Serge E. Hallyn <se...@hallyn.com>
>> Cc: Will Drewry <w...@chromium.org>
>> Link: 
>> https://lkml.kernel.org/r/c10a503d-5e35-7785-2f3d-25ed8dd63...@digikod.net
>> ---
>>  include/linux/landlock.h  |  36 +++
>>  include/linux/seccomp.h   |   8 ++
>>  include/uapi/linux/seccomp.h  |   1 +
>>  kernel/fork.c |  14 ++-
>>  kernel/seccomp.c  |   8 ++
>>  security/landlock/Makefile|   2 +-
>>  security/landlock/hooks.c |  37 +++
>>  security/landlock/hooks.h |   5 +
>>  security/landlock/init.c  |   3 +-
>>  security/landlock/providers.c | 232 
>> ++
>>  10 files changed, 342 insertions(+), 4 deletions(-)
>>  create mode 100644 security/landlock/providers.c
>>
>> diff --git a/include/linux/landlock.h b/include/linux/landlock.h
>> index 53013dc374fe..c40ee78e86e0 100644
>> --- a/include/linux/landlock.h
>> +++ b/include/linux/landlock.h
>> @@ -12,6 +12,9 @@
>>  #define _LINUX_LANDLOCK_H
>>  #ifdef CONFIG_SECURITY_LANDLOCK
>>
>> +#include  /* _LANDLOCK_SUBTYPE_EVENT_LAST */
>> +#include  /* atomic_t */
>> +
>>  /*
>>   * This is not intended for the UAPI headers. Each userland software should 
>> use
>>   * a static minimal version for the required features as explained in the
>> @@ -19,5 +22,38 @@
>>   */
>>  #define LANDLOCK_VERSION 1
>>
>> +struct landlock_rule {
>> +   atomic_t usage;
> 
> This should be refcount_t. (And I should convert seccomp to use
> refcount_t too!) :)

OK

> 
>&g

Re: [PATCH net-next v6 05/11] seccomp: Split put_seccomp_filter() with put_seccomp()

2017-04-18 Thread Mickaël Salaün

On 19/04/2017 00:23, Kees Cook wrote:
> On Tue, Mar 28, 2017 at 4:46 PM, Mickaël Salaün <m...@digikod.net> wrote:
>> The semantic is unchanged. This will be useful for the Landlock
>> integration with seccomp (next commit).
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>> Cc: Kees Cook <keesc...@chromium.org>
>> Cc: Andy Lutomirski <l...@amacapital.net>
>> Cc: Will Drewry <w...@chromium.org>
>> ---
>>  include/linux/seccomp.h |  4 ++--
>>  kernel/fork.c   |  2 +-
>>  kernel/seccomp.c| 18 +-
>>  3 files changed, 16 insertions(+), 8 deletions(-)
>>
>> diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
>> index ecc296c137cd..e25aee2cdfc0 100644
>> --- a/include/linux/seccomp.h
>> +++ b/include/linux/seccomp.h
>> @@ -77,10 +77,10 @@ static inline int seccomp_mode(struct seccomp *s)
>>  #endif /* CONFIG_SECCOMP */
>>
>>  #ifdef CONFIG_SECCOMP_FILTER
>> -extern void put_seccomp_filter(struct task_struct *tsk);
>> +extern void put_seccomp(struct task_struct *tsk);
>>  extern void get_seccomp_filter(struct task_struct *tsk);
>>  #else  /* CONFIG_SECCOMP_FILTER */
>> -static inline void put_seccomp_filter(struct task_struct *tsk)
>> +static inline void put_seccomp(struct task_struct *tsk)
>>  {
>> return;
>>  }
>> diff --git a/kernel/fork.c b/kernel/fork.c
>> index 6c463c80e93d..a27d8e67ce33 100644
>> --- a/kernel/fork.c
>> +++ b/kernel/fork.c
>> @@ -363,7 +363,7 @@ void free_task(struct task_struct *tsk)
>>  #endif
>> rt_mutex_debug_task_free(tsk);
>> ftrace_graph_exit_task(tsk);
>> -   put_seccomp_filter(tsk);
>> +   put_seccomp(tsk);
>> arch_release_task_struct(tsk);
>> if (tsk->flags & PF_KTHREAD)
>> free_kthread_struct(tsk);
>> diff --git a/kernel/seccomp.c b/kernel/seccomp.c
>> index 65f61077ad50..326f79e32127 100644
>> --- a/kernel/seccomp.c
>> +++ b/kernel/seccomp.c
>> @@ -64,6 +64,8 @@ struct seccomp_filter {
>>  /* Limit any path through the tree to 256KB worth of instructions. */
>>  #define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
>>
>> +static void put_seccomp_filter(struct seccomp_filter *filter);
> 
> Can this be reorganized easily to avoid a forward-declaration?

I didn't want to move too much code but I will.

> 
>> +
>>  /*
>>   * Endianness is explicitly ignored and left for BPF program authors to 
>> manage
>>   * as per the specific architecture.
>> @@ -314,7 +316,7 @@ static inline void seccomp_sync_threads(void)
>>  * current's path will hold a reference.  (This also
>>  * allows a put before the assignment.)
>>  */
>> -   put_seccomp_filter(thread);
>> +   put_seccomp_filter(thread->seccomp.filter);
>> smp_store_release(>seccomp.filter,
>>   caller->seccomp.filter);
>>
>> @@ -476,10 +478,11 @@ static inline void seccomp_filter_free(struct 
>> seccomp_filter *filter)
>> }
>>  }
>>
>> -/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */
>> -void put_seccomp_filter(struct task_struct *tsk)
>> +/* put_seccomp_filter - decrements the ref count of a filter */
>> +static void put_seccomp_filter(struct seccomp_filter *filter)
>>  {
>> -   struct seccomp_filter *orig = tsk->seccomp.filter;
>> +   struct seccomp_filter *orig = filter;
>> +
>> /* Clean up single-reference branches iteratively. */
>> while (orig && atomic_dec_and_test(>usage)) {
>> struct seccomp_filter *freeme = orig;
>> @@ -488,6 +491,11 @@ void put_seccomp_filter(struct task_struct *tsk)
>> }
>>  }
>>
>> +void put_seccomp(struct task_struct *tsk)
>> +{
>> +   put_seccomp_filter(tsk->seccomp.filter);
>> +}
>> +
>>  static void seccomp_init_siginfo(siginfo_t *info, int syscall, int reason)
>>  {
>> memset(info, 0, sizeof(*info));
>> @@ -914,7 +922,7 @@ long seccomp_get_filter(struct task_struct *task, 
>> unsigned long filter_off,
>> if (copy_to_user(data, fprog->filter, bpf_classic_proglen(fprog)))
>> ret = -EFAULT;
>>
>> -   put_seccomp_filter(task);
>> +   put_seccomp_filter(task->seccomp.filter);
>> return ret;
> 
> I don't like that the arguments to get_seccomp_filter() and
> put_seccomp_filter() are now different. I think they should match for
> readability.

OK, I can do that.



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v6 04/11] landlock: Add LSM hooks related to filesystem

2017-04-18 Thread Mickaël Salaün

On 19/04/2017 00:17, Kees Cook wrote:
> On Tue, Mar 28, 2017 at 4:46 PM, Mickaël Salaün <m...@digikod.net> wrote:
>> Handle 33 filesystem-related LSM hooks for the Landlock filesystem
>> event: LANDLOCK_SUBTYPE_EVENT_FS.
>>
>> A Landlock event wrap LSM hooks for similar kernel object types (e.g.
>> struct file, struct path...). Multiple LSM hooks can trigger the same
>> Landlock event.
>>
>> Landlock handle nine coarse-grained actions: read, write, execute, new,
>> get, remove, ioctl, lock and fcntl. Each of them abstract LSM hook
>> access control in a way that can be extended in the future.
>>
>> The Landlock LSM hook registration is done after other LSM to only run
>> actions from user-space, via eBPF programs, if the access was granted by
>> major (privileged) LSMs.
>>
>> Changes since v5:
>> * split hooks.[ch] into hooks.[ch] and hooks_fs.[ch]
>> * add more documentation
>> * cosmetic fixes
>>
>> Changes since v4:
>> * add LSM hook abstraction called Landlock event
>>   * use the compiler type checking to verify hooks use by an event
>>   * handle all filesystem related LSM hooks (e.g. file_permission,
>> mmap_file, sb_mount...)
>> * register BPF programs for Landlock just after LSM hooks registration
>> * move hooks registration after other LSMs
>> * add failsafes to check if a hook is not used by the kernel
>> * allow partial raw value access form the context (needed for programs
>>   generated by LLVM)
>>
>> Changes since v3:
>> * split commit
>> * add hooks dealing with struct inode and struct path pointers:
>>   inode_permission and inode_getattr
>> * add abstraction over eBPF helper arguments thanks to wrapping structs
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>> Cc: Alexei Starovoitov <a...@kernel.org>
>> Cc: Andy Lutomirski <l...@amacapital.net>
>> Cc: Daniel Borkmann <dan...@iogearbox.net>
>> Cc: David S. Miller <da...@davemloft.net>
>> Cc: James Morris <james.l.mor...@oracle.com>
>> Cc: Kees Cook <keesc...@chromium.org>
>> Cc: Serge E. Hallyn <se...@hallyn.com>
>> ---
>>  include/linux/lsm_hooks.h|   5 +
>>  security/landlock/Makefile   |   4 +-
>>  security/landlock/hooks.c| 115 +
>>  security/landlock/hooks.h| 177 ++
>>  security/landlock/hooks_fs.c | 563 
>> +++
>>  security/landlock/hooks_fs.h |  19 ++
>>  security/landlock/init.c |  13 +
>>  security/security.c  |   7 +-
>>  8 files changed, 901 insertions(+), 2 deletions(-)
>>  create mode 100644 security/landlock/hooks.c
>>  create mode 100644 security/landlock/hooks.h
>>  create mode 100644 security/landlock/hooks_fs.c
>>  create mode 100644 security/landlock/hooks_fs.h
>>
>> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
>> index e29d4c62a3c8..884289166a0e 100644
>> --- a/include/linux/lsm_hooks.h
>> +++ b/include/linux/lsm_hooks.h
>> @@ -1920,5 +1920,10 @@ void __init loadpin_add_hooks(void);
>>  #else
>>  static inline void loadpin_add_hooks(void) { };
>>  #endif
>> +#ifdef CONFIG_SECURITY_LANDLOCK
>> +extern void __init landlock_add_hooks(void);
>> +#else
>> +static inline void __init landlock_add_hooks(void) { }
>> +#endif /* CONFIG_SECURITY_LANDLOCK */
>>
>>  #endif /* ! __LINUX_LSM_HOOKS_H */
>> diff --git a/security/landlock/Makefile b/security/landlock/Makefile
>> index 7205f9a7a2ee..c0db504a6335 100644
>> --- a/security/landlock/Makefile
>> +++ b/security/landlock/Makefile
>> @@ -1,3 +1,5 @@
>> +ccflags-$(CONFIG_SECURITY_LANDLOCK) += -Werror=unused-function
> 
> Why is this needed? If it can't be avoided, a comment should exist
> here explaining why.

This is useful to catch defined but unused hooks: error out if a
HOOK_NEW_FS(foo) is not used with a HOOK_INIT_FS(foo) in the struct
security_hook_list landlock_hooks.

> 
>> [...]
>> @@ -127,3 +132,11 @@ static struct bpf_prog_type_list bpf_landlock_type 
>> __ro_after_init = {
>> .ops = _landlock_ops,
>> .type = BPF_PROG_TYPE_LANDLOCK,
>>  };
>> +
>> +void __init landlock_add_hooks(void)
>> +{
>> +   pr_info("landlock: Version %u", LANDLOCK_VERSION);
>> +   landlock_add_hooks_fs();
>> +   security_add_hooks(NULL, 0, "landlock");
>> +   bpf_register_prog_type(_landlock_type);
> 
> I'm confused by the separation of hook registration here. The call to
> security

Re: [PATCH net-next v6 02/11] bpf,landlock: Define an eBPF program type for Landlock

2017-04-16 Thread Mickaël Salaün

On 29/03/2017 01:46, Mickaël Salaün wrote:
> Add a new type of eBPF program used by Landlock rules.
> 
> This new BPF program type will be registered with the Landlock LSM
> initialization.
> 
> Add an initial Landlock Kconfig.
> 
> Changes since v5:
> * rename file hooks.c to init.c
> * fix spelling
> 
> Changes since v4:
> * merge a minimal (not enabled) LSM code and Kconfig in this commit
> 
> Changes since v3:
> * split commit
> * revamp the landlock_context:
>   * add arch, syscall_nr and syscall_cmd (ioctl, fcntl…) to be able to
> cross-check action with the event type
>   * replace args array with dedicated fields to ease the addition of new
> fields
> 
> Signed-off-by: Mickaël Salaün <m...@digikod.net>
> Cc: Alexei Starovoitov <a...@kernel.org>
> Cc: Andy Lutomirski <l...@amacapital.net>
> Cc: Daniel Borkmann <dan...@iogearbox.net>
> Cc: David S. Miller <da...@davemloft.net>
> Cc: James Morris <james.l.mor...@oracle.com>
> Cc: Kees Cook <keesc...@chromium.org>
> Cc: Serge E. Hallyn <se...@hallyn.com>
> ---
>  include/linux/landlock.h   |  23 
>  include/uapi/linux/bpf.h   | 105 +++
>  security/Kconfig   |   1 +
>  security/Makefile  |   2 +
>  security/landlock/Kconfig  |  18 ++
>  security/landlock/Makefile |   3 +
>  security/landlock/common.h |  25 +
>  security/landlock/init.c   | 123 
> +
>  tools/include/uapi/linux/bpf.h | 105 +++
>  9 files changed, 405 insertions(+)
>  create mode 100644 include/linux/landlock.h
>  create mode 100644 security/landlock/Kconfig
>  create mode 100644 security/landlock/Makefile
>  create mode 100644 security/landlock/common.h
>  create mode 100644 security/landlock/init.c
>
[...]
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 0eb71ab9b4fd..619b1f8707cc 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -114,6 +114,7 @@ enum bpf_prog_type {
>   BPF_PROG_TYPE_LWT_IN,
>   BPF_PROG_TYPE_LWT_OUT,
>   BPF_PROG_TYPE_LWT_XMIT,
> + BPF_PROG_TYPE_LANDLOCK,
>  };
>  
>  enum bpf_attach_type {
> @@ -661,4 +662,108 @@ struct xdp_md {
>   __u32 data_end;
>  };
>  
> +/**
> + * enum landlock_subtype_event - event occurring when an action is performed 
> on
> + * a particular kernel object
> + *
> + * An event is a policy decision point which exposes the same context type
> + * (especially the same arg[0-9] field types) for each rule execution.
> + *
> + * @LANDLOCK_SUBTYPE_EVENT_UNSPEC: invalid value
> + * @LANDLOCK_SUBTYPE_EVENT_FS: generic filesystem event
> + */
> +enum landlock_subtype_event {
> + LANDLOCK_SUBTYPE_EVENT_UNSPEC,
> + LANDLOCK_SUBTYPE_EVENT_FS,
> +};
> +#define _LANDLOCK_SUBTYPE_EVENT_LAST LANDLOCK_SUBTYPE_EVENT_FS
[...]
> +/**
> + * DOC: landlock_action_fs
> + *
> + * - %LANDLOCK_ACTION_FS_EXEC: execute a file or walk through a directory
> + * - %LANDLOCK_ACTION_FS_WRITE: modify a file or a directory view (which
> + *   include mount actions)
> + * - %LANDLOCK_ACTION_FS_READ: read a file or a directory
> + * - %LANDLOCK_ACTION_FS_NEW: create a file or a directory
> + * - %LANDLOCK_ACTION_FS_GET: open or receive a file
> + * - %LANDLOCK_ACTION_FS_REMOVE: unlink a file or remove a directory
> + *
> + * Each of the following actions are specific to syscall multiplexers. They
> + * fill the syscall_cmd field from  landlock_context with their custom
> + * command.
> + *
> + * - %LANDLOCK_ACTION_FS_IOCTL: ioctl command
> + * - %LANDLOCK_ACTION_FS_LOCK: flock or fcntl lock command
> + * - %LANDLOCK_ACTION_FS_FCNTL: fcntl command
> + */
> +#define LANDLOCK_ACTION_FS_EXEC  (1ULL << 0)
> +#define LANDLOCK_ACTION_FS_WRITE (1ULL << 1)
> +#define LANDLOCK_ACTION_FS_READ  (1ULL << 2)
> +#define LANDLOCK_ACTION_FS_NEW   (1ULL << 3)
> +#define LANDLOCK_ACTION_FS_GET   (1ULL << 4)
> +#define LANDLOCK_ACTION_FS_REMOVE(1ULL << 5)
> +#define LANDLOCK_ACTION_FS_IOCTL (1ULL << 6)
> +#define LANDLOCK_ACTION_FS_LOCK  (1ULL << 7)
> +#define LANDLOCK_ACTION_FS_FCNTL (1ULL << 8)
> +#define _LANDLOCK_ACTION_FS_NB   9
> +#define _LANDLOCK_ACTION_FS_MASK ((1ULL << 
> _LANDLOCK_ACTION_FS_NB) - 1)
> +
> +
> +/**
> + * struct landlock_context - context accessible to a Landlock rule
> + *
> + * @status

Re: [kernel-hardening] [PATCH net-next v6 07/11] landlock: Add ptrace restrictions

2017-04-11 Thread Mickaël Salaün

On 10/04/2017 08:48, Djalal Harouni wrote:
> On Wed, Mar 29, 2017 at 1:46 AM, Mickaël Salaün <m...@digikod.net> wrote:
>> A landlocked process has less privileges than a non-landlocked process
>> and must then be subject to additional restrictions when manipulating
>> processes. To be allowed to use ptrace(2) and related syscalls on a
>> target process, a landlocked process must have a subset of the target
>> process' rules.
>>
>> New in v6
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>> Cc: Alexei Starovoitov <a...@kernel.org>
>> Cc: Andy Lutomirski <l...@amacapital.net>
>> Cc: Daniel Borkmann <dan...@iogearbox.net>
>> Cc: David S. Miller <da...@davemloft.net>
>> Cc: James Morris <james.l.mor...@oracle.com>
>> Cc: Kees Cook <keesc...@chromium.org>
>> Cc: Serge E. Hallyn <se...@hallyn.com>
>> ---
>>  security/landlock/Makefile   |   2 +-
>>  security/landlock/hooks_ptrace.c | 126 
>> +++
>>  security/landlock/hooks_ptrace.h |  11 
>>  security/landlock/init.c |   2 +
>>  4 files changed, 140 insertions(+), 1 deletion(-)
>>  create mode 100644 security/landlock/hooks_ptrace.c
>>  create mode 100644 security/landlock/hooks_ptrace.h
>>
> [...]
> 
>> +/**
>> + * landlock_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 has Landlock rules, then the child must have at least
>> + * the same rules.  Else denied.
>> + *
>> + * Determine whether a process may access another, returning 0 if permission
>> + * granted, -errno if denied.
>> + */
>> +static int landlock_ptrace_access_check(struct task_struct *child,
>> +   unsigned int mode)
>> +{
>> +   if (!landlocked(current))
>> +   return 0;
>> +
>> +   if (!landlocked(child))
>> +   return -EPERM;
>> +
>> +   if (landlock_task_has_subset_events(current, child))
>> +   return 0;
>> +
>> +   return -EPERM;
>> +}
>> +
> 
> Maybe you want to check the mode argument here if it is a
> PTRACE_ATTACH which may translate to read/writes ? PTRACE_READ are
> normally for reads only. Or also which creds were used if this was a
> direct syscall or a filesystem call through procfs.

The idea is to mimic the behavior of UID/GID checks, namespaces and so
on. A hierarchy of Landlock rules has a similar semantic as namespaces,
at least for now with the FS event.

> 
> I'm bringing this, since you may want to make some room for landlock
> ptrace events and what others may want to do with it. Also I'm

I don't see any no problem to add a ptrace event in the future as long
as the composition with this default rule is a logical AND to allow a
ptrace action.

It would be possible to relax this default policy for rules with a
dedicated option flag, but the current behavior is a sane one from a
security point of view.

> planning to send another v2 RFC for procfs separate instances [1], the
> aim is to give LSMs a security_ptrace_access_check hook path when
> dealing with /proc// [2]  . Right now LSMs don't really have a
> security path there, and the implementation does not guarantee that.
> With this Yama ptrace scope or other LSMs may take advantage of it and
> check the 'PTRACE_MODE_READ_FSCRED' mode for filesystem accesses.

Interesting, feel free to CC me.

> That's why I think it would be better if the default landlock ptrace
> semantics are not that wide.
> 
> Thanks!
> 
> [1] https://lkml.org/lkml/2017/3/30/670
> [2] http://lxr.free-electrons.com/source/fs/proc/base.c#L719
> 

If a task is allowed to ptrace/read the memory of another task with
different privileges, the tracer could also access sensitive data not
allowed otherwise.

Do you have an use case where this constraint would be an issue?

 Mickaël



signature.asc
Description: OpenPGP digital signature


Re: [PATCH net-next v6 01/11] bpf: Add eBPF program subtype and is_valid_subtype() verifier (fwd)

2017-03-31 Thread Mickaël Salaün
Good catch, thanks again Julia!

 Mickaël

On 29/03/2017 17:14, Julia Lawall wrote:
> Size is unsigned, so not negative.
> 
> julia
> 
> -- Forwarded message --
> Date: Wed, 29 Mar 2017 23:06:01 +0800
> From: kbuild test robot <fengguang...@intel.com>
> To: kbu...@01.org
> Cc: Julia Lawall <julia.law...@lip6.fr>
> Subject: Re: [PATCH net-next v6 01/11] bpf: Add eBPF program subtype and
> is_valid_subtype() verifier
> 
> In-Reply-To: <20170328234650.19695-2-...@digikod.net>
> TO: "Mickaël Salaün" <m...@digikod.net>
> 
> Hi Mickaël,
> 
> [auto build test WARNING on net-next/master]
> 
> url:
> https://github.com/0day-ci/linux/commits/Micka-l-Sala-n/Landlock-LSM-Toward-unprivileged-sandboxing/20170329-211258
> :: branch date: 2 hours ago
> :: commit date: 2 hours ago
> 
>>> kernel/bpf/syscall.c:1041:5-9: WARNING: Unsigned expression compared with 
>>> zero: size < 0
> 
> git remote add linux-review https://github.com/0day-ci/linux
> git remote update linux-review
> git checkout 07d282aef4f60235407284c0be81d01e352e040b
> vim +1041 kernel/bpf/syscall.c
> 
> f4324551 Daniel Mack2016-11-23  1025  return -EINVAL;
> f4324551 Daniel Mack2016-11-23  1026  }
> f4324551 Daniel Mack2016-11-23  1027
> 7f677633 Alexei Starovoitov 2017-02-10  1028  return ret;
> f4324551 Daniel Mack2016-11-23  1029  }
> f4324551 Daniel Mack2016-11-23  1030  #endif /* CONFIG_CGROUP_BPF */
> f4324551 Daniel Mack2016-11-23  1031
> 99c55f7d Alexei Starovoitov 2014-09-26  1032  SYSCALL_DEFINE3(bpf, int, cmd, 
> union bpf_attr __user *, uattr, unsigned int, size)
> 99c55f7d Alexei Starovoitov 2014-09-26  1033  {
> 99c55f7d Alexei Starovoitov 2014-09-26  1034  union bpf_attr attr = 
> {};
> 99c55f7d Alexei Starovoitov 2014-09-26  1035  int err;
> 99c55f7d Alexei Starovoitov 2014-09-26  1036
> 1be7f75d Alexei Starovoitov 2015-10-07  1037  if 
> (!capable(CAP_SYS_ADMIN) && sysctl_unprivileged_bpf_disabled)
> 99c55f7d Alexei Starovoitov 2014-09-26  1038      return -EPERM;
> 99c55f7d Alexei Starovoitov 2014-09-26  1039
> 07d282ae Mickaël Salaün 2017-03-29  1040  size = 
> check_user_buf((void __user *)uattr, size, sizeof(attr));
> 07d282ae Mickaël Salaün 2017-03-29 @1041  if (size < 0)
> 07d282ae Mickaël Salaün 2017-03-29  1042  return size;
> 99c55f7d Alexei Starovoitov 2014-09-26  1043
> 99c55f7d Alexei Starovoitov 2014-09-26  1044  /* copy attributes from 
> user space, may be less than sizeof(bpf_attr) */
> 99c55f7d Alexei Starovoitov 2014-09-26  1045  if 
> (copy_from_user(, uattr, size) != 0)
> 99c55f7d Alexei Starovoitov 2014-09-26  1046  return -EFAULT;
> 99c55f7d Alexei Starovoitov 2014-09-26  1047
> 99c55f7d Alexei Starovoitov 2014-09-26  1048  switch (cmd) {
> 99c55f7d Alexei Starovoitov 2014-09-26  1049  case BPF_MAP_CREATE:
> 
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation
> 



signature.asc
Description: OpenPGP digital signature


Re: [kernel-hardening] [PATCH net-next v6 06/11] seccomp,landlock: Handle Landlock events per process hierarchy

2017-03-31 Thread Mickaël Salaün


On 29/03/2017 12:35, Djalal Harouni wrote:
> On Wed, Mar 29, 2017 at 1:46 AM, Mickaël Salaün <m...@digikod.net> wrote:

>> @@ -25,6 +30,9 @@ struct seccomp_filter;
>>  struct seccomp {
>> int mode;
>> struct seccomp_filter *filter;
>> +#if defined(CONFIG_SECCOMP_FILTER) && defined(CONFIG_SECURITY_LANDLOCK)
>> +   struct landlock_events *landlock_events;
>> +#endif /* CONFIG_SECCOMP_FILTER && CONFIG_SECURITY_LANDLOCK */
>>  };
> 
> Sorry if this was discussed before, but since this is mean to be a
> stackable LSM, I'm wondering if later you could move the events from
> seccomp, and go with a security_task_alloc() model [1] ?
> 
> Thanks!
> 
> [1] 
> http://kernsec.org/pipermail/linux-security-module-archive/2017-March/000184.html
> 

Landlock use the seccomp syscall to attach a rule to a process and using
struct seccomp to store this rule make sense. There is currently no way
to store multiple task->security, which is needed for a stackable LSM
like Landlock, but we could move the events there if needed in the future.

 Mickaël



signature.asc
Description: OpenPGP digital signature


[PATCH net-next v6 03/11] bpf: Define handle_fs and add a new helper bpf_handle_fs_get_mode()

2017-03-28 Thread Mickaël Salaün
Add an eBPF function bpf_handle_fs_get_mode(handle_fs) to get the mode
of a an abstract object wrapping either a file, a dentry, a path, or an
inode.

Changes since v5:
* cosmetic fixes and rebase

Changes since v4:
* use a file abstraction (handle) to wrap inode, dentry, path and file
  structs
* remove bpf_landlock_cmp_fs_beneath()
* rename the BPF helper and move it to kernel/bpf/
* tighten helpers accessible by a Landlock rule

Changes since v3:
* remove bpf_landlock_cmp_fs_prop() (suggested by Alexie Starovoitov)
* add hooks dealing with struct inode and struct path pointers:
  inode_permission and inode_getattr
* add abstraction over eBPF helper arguments thanks to wrapping structs
* add bpf_landlock_get_fs_mode() helper to check file type and mode
* merge WARN_ON() (suggested by Kees Cook)
* fix and update bpf_helpers.h
* use BPF_CALL_* for eBPF helpers (suggested by Alexie Starovoitov)
* make handle arraymap safe (RCU) and remove buggy synchronize_rcu()
* factor out the arraymay walk
* use size_t to index array (suggested by Jann Horn)

Changes since v2:
* add MNT_INTERNAL check to only add file handle from user-visible FS
  (e.g. no anonymous inode)
* replace struct file* with struct path* in map_landlock_handle
* add BPF protos
* fix bpf_landlock_cmp_fs_prop_with_struct_file()

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
Cc: Jann Horn <j...@thejh.net>
---
 include/linux/bpf.h| 33 +++
 include/uapi/linux/bpf.h   | 10 +++-
 kernel/bpf/Makefile|  2 +-
 kernel/bpf/helpers_fs.c| 52 ++
 kernel/bpf/verifier.c  |  6 +
 samples/bpf/bpf_helpers.h  |  2 ++
 security/landlock/init.c   |  6 +
 tools/include/uapi/linux/bpf.h | 10 +++-
 8 files changed, 118 insertions(+), 3 deletions(-)
 create mode 100644 kernel/bpf/helpers_fs.c

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 1cb407bd8ef7..a2e53c22e450 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -15,6 +15,11 @@
 #include 
 #include 
 
+/* FS helpers */
+#include  /* struct dentry */
+#include  /* struct file, struct inode */
+#include  /* struct path */
+
 struct perf_event;
 struct bpf_map;
 
@@ -84,6 +89,8 @@ enum bpf_arg_type {
 
ARG_PTR_TO_CTX, /* pointer to context */
ARG_ANYTHING,   /* any (initialized) argument is ok */
+
+   ARG_CONST_PTR_TO_HANDLE_FS, /* pointer to an abstract FS struct */
 };
 
 /* type of values returned from helper functions */
@@ -150,6 +157,9 @@ enum bpf_reg_type {
 * map element.
 */
PTR_TO_MAP_VALUE_ADJ,
+
+   /* FS helpers */
+   CONST_PTR_TO_HANDLE_FS,
 };
 
 struct bpf_prog;
@@ -222,6 +232,26 @@ struct bpf_event_entry {
struct rcu_head rcu;
 };
 
+/* FS helpers */
+enum bpf_handle_fs_type {
+   BPF_HANDLE_FS_TYPE_NONE,
+   BPF_HANDLE_FS_TYPE_FILE,
+   BPF_HANDLE_FS_TYPE_INODE,
+   BPF_HANDLE_FS_TYPE_PATH,
+   BPF_HANDLE_FS_TYPE_DENTRY,
+};
+
+struct bpf_handle_fs {
+   enum bpf_handle_fs_type type;
+   union {
+   struct file *file;
+   struct inode *inode;
+   const struct path *path;
+   struct dentry *dentry;
+   };
+};
+
+
 u64 bpf_tail_call(u64 ctx, u64 r2, u64 index, u64 r4, u64 r5);
 u64 bpf_get_stackid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
 
@@ -362,6 +392,9 @@ extern const struct bpf_func_proto bpf_skb_vlan_push_proto;
 extern const struct bpf_func_proto bpf_skb_vlan_pop_proto;
 extern const struct bpf_func_proto bpf_get_stackid_proto;
 
+/* FS helpers */
+extern const struct bpf_func_proto bpf_handle_fs_get_mode_proto;
+
 /* Shared helpers among cBPF and eBPF. */
 void bpf_user_rnd_init_once(void);
 u64 bpf_user_rnd_u32(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 619b1f8707cc..d35948634667 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -483,6 +483,13 @@ union bpf_attr {
  * @skb: pointer to skb
  * Return: uid of the socket owner on success or 0 if the socket pointer
  * inside sk_buff is NULL
+ *
+ * s64 bpf_handle_fs_get_mode(handle_fs)
+ * Get the mode of a struct bpf_handle_fs
+ * fs: struct bpf_handle_fs address
+ * Return:
+ *   >= 0 file mode
+ *   < 0 error
  */
 #define __BPF_FUNC_MAPPER(FN)  \
FN(unspec), \
@@ -532,7 +539,8 @@ union bpf_attr {
FN(xdp_adjust_head),\
FN(probe_read_str), \
FN(get_socket_cookie), 

[PATCH net-next v6 00/11] Landlock LSM: Toward unprivileged sandboxing

2017-03-28 Thread Mickaël Salaün
ince v1

* focus on the LSM hooks, not the syscalls:
  * much more simple implementation
  * does not need audit cache tricks to avoid race conditions
  * more simple to use and more generic because using the LSM hook abstraction
directly
  * more efficient because only checking in LSM hooks
  * architecture agnostic
* switch from cBPF to eBPF:
  * new eBPF program types dedicated to Landlock
  * custom functions used by the eBPF program
  * gain some new features (e.g. 10 registers, can load values of different
size, LLVM translator) but only a few functions allowed and a dedicated 
map
type
  * new context: LSM hook ID, cookie and LSM hook arguments
  * need to set the sysctl kernel.unprivileged_bpf_disable to 0 (default value)
to be able to load hook filters as unprivileged users
* smaller and simpler:
  * no more checker groups but dedicated arraymap of handles
  * simpler userland structs thanks to eBPF functions
* distinctive name: Landlock


[1] https://lkml.kernel.org/r/20170222012632.4196-1-...@digikod.net
[2] https://lkml.kernel.org/r/5828776a.1010...@digikod.net
[3] 
https://lkml.kernel.org/r/1477390454-12553-1-git-send-email-dan...@zonque.org
[4] 
https://lkml.kernel.org/r/20160829114542.GA20836@ircssh.c.rugged-nimbus-611.internal
[5] https://lkml.kernel.org/r/20161221231506.19800-1-...@digikod.net

Regards,

Mickaël Salaün (11):
  bpf: Add eBPF program subtype and is_valid_subtype() verifier
  bpf,landlock: Define an eBPF program type for Landlock
  bpf: Define handle_fs and add a new helper bpf_handle_fs_get_mode()
  landlock: Add LSM hooks related to filesystem
  seccomp: Split put_seccomp_filter() with put_seccomp()
  seccomp,landlock: Handle Landlock events per process hierarchy
  landlock: Add ptrace restrictions
  bpf: Add a Landlock sandbox example
  seccomp: Enhance test_harness with an assert step mechanism
  bpf,landlock: Add tests for Landlock
  landlock: Add user and kernel documentation for Landlock

 Documentation/security/index.rst   |   1 +
 Documentation/security/landlock/index.rst  |  19 +
 Documentation/security/landlock/kernel.rst | 132 +
 Documentation/security/landlock/user.rst   | 307 +++
 include/linux/bpf.h|  40 +-
 include/linux/filter.h |   2 +
 include/linux/landlock.h   |  59 +++
 include/linux/lsm_hooks.h  |   5 +
 include/linux/seccomp.h|  12 +-
 include/uapi/linux/bpf.h   | 126 -
 include/uapi/linux/seccomp.h   |   1 +
 kernel/bpf/Makefile|   2 +-
 kernel/bpf/helpers_fs.c|  52 ++
 kernel/bpf/syscall.c   |  89 ++--
 kernel/bpf/verifier.c  |  22 +-
 kernel/fork.c  |  16 +-
 kernel/seccomp.c   |  26 +-
 kernel/trace/bpf_trace.c   |  15 +-
 net/core/filter.c  |  48 +-
 samples/bpf/Makefile   |   4 +
 samples/bpf/bpf_helpers.h  |   2 +
 samples/bpf/bpf_load.c |  34 +-
 samples/bpf/cookie_uid_helper_example.c|   2 +-
 samples/bpf/fds_example.c  |   2 +-
 samples/bpf/landlock1_kern.c   |  46 ++
 samples/bpf/landlock1_user.c   | 102 
 samples/bpf/sock_example.c |   3 +-
 samples/bpf/test_cgrp2_attach.c|   2 +-
 samples/bpf/test_cgrp2_attach2.c   |   2 +-
 samples/bpf/test_cgrp2_sock.c  |   2 +-
 security/Kconfig   |   1 +
 security/Makefile  |   2 +
 security/landlock/Kconfig  |  18 +
 security/landlock/Makefile |   5 +
 security/landlock/common.h |  25 +
 security/landlock/hooks.c  | 152 ++
 security/landlock/hooks.h  | 182 +++
 security/landlock/hooks_fs.c   | 563 +
 security/landlock/hooks_fs.h   |  19 +
 security/landlock/hooks_ptrace.c   | 126 +
 security/landlock/hooks_ptrace.h   |  11 +
 security/landlock/init.c   | 145 ++
 security/landlock/providers.c  | 232 +
 security/security.c|   7 +-
 tools/include/uapi/linux/bpf.h | 126 -
 tools/lib/bpf/bpf.c|   5 +-
 tools/lib/bpf/bpf.h|   2 +-
 tools/lib/bpf/libbpf.c |   4 +-
 tools/perf/tests/bpf.c 

[PATCH net-next v6 01/11] bpf: Add eBPF program subtype and is_valid_subtype() verifier

2017-03-28 Thread Mickaël Salaün
The goal of the program subtype is to be able to have different static
fine-grained verifications for a unique program type.

The struct bpf_verifier_ops gets a new optional function:
is_valid_subtype(). This new verifier is called at the beginning of the
eBPF program verification to check if the (optional) program subtype is
valid.

For now, only Landlock eBPF programs are using a program subtype (see
next commit) but this could be used by other program types in the future.

Changes since v5:
* use a prog_subtype pointer and make it future-proof
* add subtype test
* constify bpf_load_program()'s subtype argument
* cleanup subtype initialization
* rebase

Changes since v4:
* replace the "status" field with "version" (more generic)
* replace the "access" field with "ability" (less confusing)

Changes since v3:
* remove the "origin" field
* add an "option" field
* cleanup comments

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Link: https://lkml.kernel.org/r/20160827205559.ga43...@ast-mbp.thefacebook.com
---
 include/linux/bpf.h |  7 ++-
 include/linux/filter.h  |  2 +
 include/uapi/linux/bpf.h| 11 
 kernel/bpf/syscall.c| 89 +++--
 kernel/bpf/verifier.c   | 16 +-
 kernel/trace/bpf_trace.c| 15 +++--
 net/core/filter.c   | 48 ++--
 samples/bpf/bpf_load.c  |  3 +-
 samples/bpf/cookie_uid_helper_example.c |  2 +-
 samples/bpf/fds_example.c   |  2 +-
 samples/bpf/sock_example.c  |  3 +-
 samples/bpf/test_cgrp2_attach.c |  2 +-
 samples/bpf/test_cgrp2_attach2.c|  2 +-
 samples/bpf/test_cgrp2_sock.c   |  2 +-
 tools/include/uapi/linux/bpf.h  | 11 
 tools/lib/bpf/bpf.c |  5 +-
 tools/lib/bpf/bpf.h |  2 +-
 tools/lib/bpf/libbpf.c  |  4 +-
 tools/perf/tests/bpf.c  |  2 +-
 tools/testing/selftests/bpf/test_tag.c  |  2 +-
 tools/testing/selftests/bpf/test_verifier.c | 16 +-
 21 files changed, 175 insertions(+), 71 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 2ae39a3e9ead..1cb407bd8ef7 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -156,19 +156,22 @@ struct bpf_prog;
 
 struct bpf_verifier_ops {
/* return eBPF function prototype for verification */
-   const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id 
func_id);
+   const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id func_id,
+ union bpf_prog_subtype *prog_subtype);
 
/* return true if 'size' wide access at offset 'off' within bpf_context
 * with 'type' (read or write) is allowed
 */
bool (*is_valid_access)(int off, int size, enum bpf_access_type type,
-   enum bpf_reg_type *reg_type);
+   enum bpf_reg_type *reg_type,
+   union bpf_prog_subtype *prog_subtype);
int (*gen_prologue)(struct bpf_insn *insn, bool direct_write,
const struct bpf_prog *prog);
u32 (*convert_ctx_access)(enum bpf_access_type type,
  const struct bpf_insn *src,
  struct bpf_insn *dst,
  struct bpf_prog *prog);
+   bool (*is_valid_subtype)(union bpf_prog_subtype *prog_subtype);
 };
 
 struct bpf_prog_type_list {
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 511fe910bf1d..f5eb40a9aaa1 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -419,6 +419,8 @@ struct bpf_prog {
enum bpf_prog_type  type;   /* Type of BPF program */
u32 len;/* Number of filter blocks */
u8  tag[BPF_TAG_SIZE];
+   u8  has_subtype;
+   union bpf_prog_subtype  subtype;/* Fine-grained verifications */
struct bpf_prog_aux *aux;   /* Auxiliary fields */
struct sock_fprog_kern  *orig_prog; /* Original BPF program */
unsigned int(*bpf_func)(const void *ctx,
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 28317a04c34d..0eb71ab9b4fd 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -147,6 +147,15 @@ enum bpf_attach_type {
  */
 #define BPF_F_NO_COMMON_LRU(1U << 1)
 
+union bpf_prog_subtype {
+   struct {
+   __u32   versio

[PATCH net-next v6 06/11] seccomp,landlock: Handle Landlock events per process hierarchy

2017-03-28 Thread Mickaël Salaün
The seccomp(2) syscall can be used by a task to apply a Landlock rule to
itself. As a seccomp filter, a Landlock rule is enforced for the current
task and all its future children. A rule is immutable and a task can
only add new restricting rules to itself, forming a chain of rules.

A Landlock rule is tied to a Landlock event. If the use of a kernel
object is allowed by the other Linux security mechanisms (e.g. DAC,
capabilities, other LSM), then a Landlock event related to this kind of
object is triggered. The chain of rules for this event is then
evaluated. Each rule return a 32-bit value which can deny the use of a
kernel object with a non-zero value. If every rules of the chain return
zero, then the use of the object is allowed.

Changes since v5:
* remove struct landlock_node and use a similar inheritance mechanisme
  as seccomp-bpf (requested by Andy Lutomirski)
* rename SECCOMP_ADD_LANDLOCK_RULE to SECCOMP_APPEND_LANDLOCK_RULE
* rename file manager.c to providers.c
* add comments
* typo and cosmetic fixes

Changes since v4:
* merge manager and seccomp patches
* return -EFAULT in seccomp(2) when user_bpf_fd is null to easely check
  if Landlock is supported
* only allow a process with the global CAP_SYS_ADMIN to use Landlock
  (will be lifted in the future)
* add an early check to exit as soon as possible if the current process
  does not have Landlock rules

Changes since v3:
* remove the hard link with seccomp (suggested by Andy Lutomirski and
  Kees Cook):
  * remove the cookie which could imply multiple evaluation of Landlock
rules
  * remove the origin field in struct landlock_data
* remove documentation fix (merged upstream)
* rename the new seccomp command to SECCOMP_ADD_LANDLOCK_RULE
* internal renaming
* split commit
* new design to be able to inherit on the fly the parent rules

Changes since v2:
* Landlock programs can now be run without seccomp filter but for any
  syscall (from the process) or interruption
* move Landlock related functions and structs into security/landlock/*
  (to manage cgroups as well)
* fix seccomp filter handling: run Landlock programs for each of their
  legitimate seccomp filter
* properly clean up all seccomp results
* cosmetic changes to ease the understanding
* fix some ifdef

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andrew Morton <a...@linux-foundation.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
Cc: Will Drewry <w...@chromium.org>
Link: https://lkml.kernel.org/r/c10a503d-5e35-7785-2f3d-25ed8dd63...@digikod.net
---
 include/linux/landlock.h  |  36 +++
 include/linux/seccomp.h   |   8 ++
 include/uapi/linux/seccomp.h  |   1 +
 kernel/fork.c |  14 ++-
 kernel/seccomp.c  |   8 ++
 security/landlock/Makefile|   2 +-
 security/landlock/hooks.c |  37 +++
 security/landlock/hooks.h |   5 +
 security/landlock/init.c  |   3 +-
 security/landlock/providers.c | 232 ++
 10 files changed, 342 insertions(+), 4 deletions(-)
 create mode 100644 security/landlock/providers.c

diff --git a/include/linux/landlock.h b/include/linux/landlock.h
index 53013dc374fe..c40ee78e86e0 100644
--- a/include/linux/landlock.h
+++ b/include/linux/landlock.h
@@ -12,6 +12,9 @@
 #define _LINUX_LANDLOCK_H
 #ifdef CONFIG_SECURITY_LANDLOCK
 
+#include  /* _LANDLOCK_SUBTYPE_EVENT_LAST */
+#include  /* atomic_t */
+
 /*
  * This is not intended for the UAPI headers. Each userland software should use
  * a static minimal version for the required features as explained in the
@@ -19,5 +22,38 @@
  */
 #define LANDLOCK_VERSION 1
 
+struct landlock_rule {
+   atomic_t usage;
+   struct landlock_rule *prev;
+   struct bpf_prog *prog;
+};
+
+/**
+ * struct landlock_events - Landlock event rules enforced on a thread
+ *
+ * This is used for low performance impact when forking a process. Instead of
+ * copying the full array and incrementing the usage of each entries, only
+ * create a pointer to  landlock_events and increments its usage. When
+ * appending a new rule, if  landlock_events is shared with other tasks,
+ * then duplicate it and append the rule to this new  landlock_events.
+ *
+ * @usage: reference count to manage the object lifetime. When a thread need to
+ * add Landlock rules and if @usage is greater than 1, then the thread
+ * must duplicate  landlock_events to not change the children's
+ * rules as well.
+ * @rules: array of non-NULL  landlock_rule pointers
+ */
+struct landlock_events {
+   atomic_t usage;
+   struct landlock_rule *rules[_LANDLOCK_SUBTYPE_EVENT_LAST];
+};
+
+void put_landlock_events(struct landlock_events *events);
+
+#ifdef CONFIG_SECCOMP_FILTER
+int landlock_seccomp_append_prog(unsigned int flags,
+   

[PATCH net-next v6 11/11] landlock: Add user and kernel documentation for Landlock

2017-03-28 Thread Mickaël Salaün
This documentation can be built with the Sphinx framework.

Changes since v5:
* update the rule hierarchy inheritance explanation
* briefly explain ctx->arg2
* add ptrace restrictions
* explain EPERM
* update example (subtype)
* use ":manpage:"

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Jonathan Corbet <cor...@lwn.net>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---
 Documentation/security/index.rst   |   1 +
 Documentation/security/landlock/index.rst  |  19 ++
 Documentation/security/landlock/kernel.rst | 132 +
 Documentation/security/landlock/user.rst   | 307 +
 4 files changed, 459 insertions(+)
 create mode 100644 Documentation/security/landlock/index.rst
 create mode 100644 Documentation/security/landlock/kernel.rst
 create mode 100644 Documentation/security/landlock/user.rst

diff --git a/Documentation/security/index.rst b/Documentation/security/index.rst
index 9bae6bb20e7f..21a5a6b6e666 100644
--- a/Documentation/security/index.rst
+++ b/Documentation/security/index.rst
@@ -5,3 +5,4 @@ Security documentation
 .. toctree::
 
tpm/index
+   landlock/index
diff --git a/Documentation/security/landlock/index.rst 
b/Documentation/security/landlock/index.rst
new file mode 100644
index ..8afde6a5805c
--- /dev/null
+++ b/Documentation/security/landlock/index.rst
@@ -0,0 +1,19 @@
+=
+Landlock LSM: programmatic access control
+=
+
+Landlock is a stackable Linux Security Module (LSM) that makes it possible to
+create security sandboxes.  This kind of sandbox is expected to help mitigate
+the security impact of bugs or unexpected/malicious behaviors in user-space
+applications.  The current version allows only a process with the global
+CAP_SYS_ADMIN capability to create such sandboxes but the ultimate goal of
+Landlock is to empower any process, including unprivileged ones, to securely
+restrict themselves.  Landlock is inspired by seccomp-bpf but instead of
+filtering syscalls and their raw arguments, a Landlock rule can inspect the use
+of kernel objects like files and hence make a decision according to the kernel
+semantic.
+
+.. toctree::
+
+user
+kernel
diff --git a/Documentation/security/landlock/kernel.rst 
b/Documentation/security/landlock/kernel.rst
new file mode 100644
index ..49155499f9c2
--- /dev/null
+++ b/Documentation/security/landlock/kernel.rst
@@ -0,0 +1,132 @@
+==
+Landlock: kernel documentation
+==
+
+eBPF properties
+===
+
+To get an expressive language while still being safe and small, Landlock is
+based on eBPF. Landlock should be usable by untrusted processes and must
+therefore expose a minimal attack surface. The eBPF bytecode is minimal,
+powerful, widely used and designed to be used by untrusted applications. Thus,
+reusing the eBPF support in the kernel enables a generic approach while
+minimizing new code.
+
+An eBPF program has access to an eBPF context containing some fields including
+event arguments (i.e. arg1 and arg2). These arguments can be used directly or
+passed to helper functions according to their types. It is then possible to do
+complex access checks without race conditions or inconsistent evaluation (i.e.
+`incorrect mirroring of the OS code and state
+<https://www.internetsociety.org/doc/traps-and-pitfalls-practical-problems-system-call-interposition-based-security-tools>`_).
+
+A Landlock event describes a particular access type.  For now, there is only
+one event type dedicated to filesystem related operations:
+LANDLOCK_SUBTYPE_EVENT_FS.  A Landlock rule is tied to one event type.  This
+makes it possible to statically check context accesses, potentially performed
+by such rule, and hence prevents kernel address leaks and ensure the right use
+of event arguments with eBPF functions.  Any user can add multiple Landlock
+rules per Landlock event.  They are stacked and evaluated one after the other,
+starting from the most recent rule, as seccomp-bpf does with its filters.
+Underneath, an event is an abstraction over a set of LSM hooks.
+
+
+Guiding principles
+==
+
+Unprivileged use
+
+
+* Everything potentially security sensitive which is exposed to a Landlock
+  rule, through functions or context, shall have an associated ability flag to
+  specify which kind of privilege a process must have to load such a rule.
+* Every ability flag expresses a semantic goal (e.g. debug, process
+  introspection, process modification) potentially tied to a set of
+  capabilities.
+* Landlock 

[PATCH net-next v6 02/11] bpf,landlock: Define an eBPF program type for Landlock

2017-03-28 Thread Mickaël Salaün
Add a new type of eBPF program used by Landlock rules.

This new BPF program type will be registered with the Landlock LSM
initialization.

Add an initial Landlock Kconfig.

Changes since v5:
* rename file hooks.c to init.c
* fix spelling

Changes since v4:
* merge a minimal (not enabled) LSM code and Kconfig in this commit

Changes since v3:
* split commit
* revamp the landlock_context:
  * add arch, syscall_nr and syscall_cmd (ioctl, fcntl…) to be able to
cross-check action with the event type
  * replace args array with dedicated fields to ease the addition of new
fields

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---
 include/linux/landlock.h   |  23 
 include/uapi/linux/bpf.h   | 105 +++
 security/Kconfig   |   1 +
 security/Makefile  |   2 +
 security/landlock/Kconfig  |  18 ++
 security/landlock/Makefile |   3 +
 security/landlock/common.h |  25 +
 security/landlock/init.c   | 123 +
 tools/include/uapi/linux/bpf.h | 105 +++
 9 files changed, 405 insertions(+)
 create mode 100644 include/linux/landlock.h
 create mode 100644 security/landlock/Kconfig
 create mode 100644 security/landlock/Makefile
 create mode 100644 security/landlock/common.h
 create mode 100644 security/landlock/init.c

diff --git a/include/linux/landlock.h b/include/linux/landlock.h
new file mode 100644
index ..53013dc374fe
--- /dev/null
+++ b/include/linux/landlock.h
@@ -0,0 +1,23 @@
+/*
+ * Landlock LSM - public kernel headers
+ *
+ * Copyright © 2017 Mickaël Salaün <m...@digikod.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _LINUX_LANDLOCK_H
+#define _LINUX_LANDLOCK_H
+#ifdef CONFIG_SECURITY_LANDLOCK
+
+/*
+ * This is not intended for the UAPI headers. Each userland software should use
+ * a static minimal version for the required features as explained in the
+ * documentation.
+ */
+#define LANDLOCK_VERSION 1
+
+#endif /* CONFIG_SECURITY_LANDLOCK */
+#endif /* _LINUX_LANDLOCK_H */
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 0eb71ab9b4fd..619b1f8707cc 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -114,6 +114,7 @@ enum bpf_prog_type {
BPF_PROG_TYPE_LWT_IN,
BPF_PROG_TYPE_LWT_OUT,
BPF_PROG_TYPE_LWT_XMIT,
+   BPF_PROG_TYPE_LANDLOCK,
 };
 
 enum bpf_attach_type {
@@ -661,4 +662,108 @@ struct xdp_md {
__u32 data_end;
 };
 
+/**
+ * enum landlock_subtype_event - event occurring when an action is performed on
+ * a particular kernel object
+ *
+ * An event is a policy decision point which exposes the same context type
+ * (especially the same arg[0-9] field types) for each rule execution.
+ *
+ * @LANDLOCK_SUBTYPE_EVENT_UNSPEC: invalid value
+ * @LANDLOCK_SUBTYPE_EVENT_FS: generic filesystem event
+ */
+enum landlock_subtype_event {
+   LANDLOCK_SUBTYPE_EVENT_UNSPEC,
+   LANDLOCK_SUBTYPE_EVENT_FS,
+};
+#define _LANDLOCK_SUBTYPE_EVENT_LAST LANDLOCK_SUBTYPE_EVENT_FS
+
+/**
+ * DOC: landlock_subtype_access
+ *
+ * eBPF context and functions allowed for a rule
+ *
+ * - LANDLOCK_SUBTYPE_ABILITY_WRITE: allows to directly send notification to
+ *   userland (e.g. through a map), which may leaks sensitive information
+ * - LANDLOCK_SUBTYPE_ABILITY_DEBUG: allows to do debug actions (e.g. writing
+ *   logs), which may be dangerous and should only be used for rule testing
+ */
+#define LANDLOCK_SUBTYPE_ABILITY_WRITE (1ULL << 0)
+#define LANDLOCK_SUBTYPE_ABILITY_DEBUG (1ULL << 1)
+#define _LANDLOCK_SUBTYPE_ABILITY_NB   2
+#define _LANDLOCK_SUBTYPE_ABILITY_MASK ((1ULL << 
_LANDLOCK_SUBTYPE_ABILITY_NB) - 1)
+
+/*
+ * Future options for a Landlock rule (e.g. run even if a previous rule denied
+ * an action).
+ */
+#define _LANDLOCK_SUBTYPE_OPTION_NB0
+#define _LANDLOCK_SUBTYPE_OPTION_MASK  ((1ULL << 
_LANDLOCK_SUBTYPE_OPTION_NB) - 1)
+
+/*
+ * Status visible in the @status field of a context (e.g. already called in
+ * this syscall session, with same args...).
+ *
+ * The @status field exposed to a rule shall depend on the rule version.
+ */
+#define _LANDLOCK_SUBTYPE_STATUS_NB0
+#define _LANDLOCK_SUBTYPE_STATUS_MASK  ((1ULL << 
_LANDLOCK_SUBTYPE_STATUS_NB) - 1)
+
+/**
+ * DOC: landlock_action_fs
+ *
+ * - %LANDLOCK_ACTION_FS_EXEC: execute a file or wa

[PATCH net-next v6 09/11] seccomp: Enhance test_harness with an assert step mechanism

2017-03-28 Thread Mickaël Salaün
This is useful to return an information about the error without being
able to write to TH_LOG_STREAM.

Helpers from test_harness.h may be useful outside of the seccomp
directory.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Shuah Khan <sh...@kernel.org>
Cc: Will Drewry <w...@chromium.org>
---
 tools/testing/selftests/seccomp/test_harness.h | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/seccomp/test_harness.h 
b/tools/testing/selftests/seccomp/test_harness.h
index a786c69c7584..77e407663e06 100644
--- a/tools/testing/selftests/seccomp/test_harness.h
+++ b/tools/testing/selftests/seccomp/test_harness.h
@@ -397,7 +397,7 @@ struct __test_metadata {
const char *name;
void (*fn)(struct __test_metadata *);
int termsig;
-   int passed;
+   __s8 passed;
int trigger; /* extra handler after the evaluation */
struct __test_metadata *prev, *next;
 };
@@ -476,6 +476,12 @@ void __run_test(struct __test_metadata *t)
"instead of by signal (code: %d)\n",
t->name,
WEXITSTATUS(status));
+   } else if (t->passed < 0) {
+   fprintf(TH_LOG_STREAM,
+   "%s: Failed at step #%d\n",
+   t->name,
+   t->passed * -1);
+   t->passed = 0;
}
} else if (WIFSIGNALED(status)) {
t->passed = 0;
-- 
2.11.0



[PATCH net-next v6 10/11] bpf,landlock: Add tests for Landlock

2017-03-28 Thread Mickaël Salaün
Test basic context access, ptrace protection and filesystem event with
multiple cases.

Changes since v5:
* add subtype test
* add ptrace tests
* split and rename files
* cleanup and rebase

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
Cc: Shuah Khan <sh...@kernel.org>
Cc: Will Drewry <w...@chromium.org>
---
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/bpf/test_verifier.c|  64 +
 tools/testing/selftests/landlock/.gitignore|   4 +
 tools/testing/selftests/landlock/Makefile  |  47 
 tools/testing/selftests/landlock/rules/Makefile|  52 
 tools/testing/selftests/landlock/rules/README.rst  |   1 +
 .../testing/selftests/landlock/rules/bpf_helpers.h |   1 +
 .../testing/selftests/landlock/rules/fs_no_open.c  |  31 +++
 .../selftests/landlock/rules/fs_read_only.c|  31 +++
 tools/testing/selftests/landlock/test.h|  35 +++
 tools/testing/selftests/landlock/test_base.c   |  31 +++
 tools/testing/selftests/landlock/test_fs.c | 305 +
 tools/testing/selftests/landlock/test_ptrace.c | 161 +++
 13 files changed, 764 insertions(+)
 create mode 100644 tools/testing/selftests/landlock/.gitignore
 create mode 100644 tools/testing/selftests/landlock/Makefile
 create mode 100644 tools/testing/selftests/landlock/rules/Makefile
 create mode 12 tools/testing/selftests/landlock/rules/README.rst
 create mode 12 tools/testing/selftests/landlock/rules/bpf_helpers.h
 create mode 100644 tools/testing/selftests/landlock/rules/fs_no_open.c
 create mode 100644 tools/testing/selftests/landlock/rules/fs_read_only.c
 create mode 100644 tools/testing/selftests/landlock/test.h
 create mode 100644 tools/testing/selftests/landlock/test_base.c
 create mode 100644 tools/testing/selftests/landlock/test_fs.c
 create mode 100644 tools/testing/selftests/landlock/test_ptrace.c

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index d8593f1251ec..b584ad456428 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -12,6 +12,7 @@ TARGETS += gpio
 TARGETS += intel_pstate
 TARGETS += ipc
 TARGETS += kcmp
+TARGETS += landlock
 TARGETS += lib
 TARGETS += membarrier
 TARGETS += memfd
diff --git a/tools/testing/selftests/bpf/test_verifier.c 
b/tools/testing/selftests/bpf/test_verifier.c
index daa87dd7c80e..77255b14871e 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -4536,6 +4536,70 @@ static struct bpf_test tests[] = {
.result = REJECT,
.has_prog_subtype = true,
},
+   {
+   "missing subtype",
+   .insns = {
+   BPF_MOV32_IMM(BPF_REG_0, 0),
+   BPF_EXIT_INSN(),
+   },
+   .errstr = "",
+   .result = REJECT,
+   .prog_type = BPF_PROG_TYPE_LANDLOCK,
+   },
+   {
+   "landlock/fs: always accept",
+   .insns = {
+   BPF_MOV32_IMM(BPF_REG_0, 0),
+   BPF_EXIT_INSN(),
+   },
+   .result = ACCEPT,
+   .prog_type = BPF_PROG_TYPE_LANDLOCK,
+   .has_prog_subtype = true,
+   .prog_subtype = {
+   .landlock_rule = {
+   .version = 1,
+   .event = LANDLOCK_SUBTYPE_EVENT_FS,
+   }
+   },
+   },
+   {
+   "landlock/fs: read context",
+   .insns = {
+   BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
+   BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, status)),
+   /* test operations on raw values */
+   BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1),
+   BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, arch)),
+   BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1),
+   BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, syscall_nr)),
+   BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1),
+   BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, syscall_cmd)),
+   BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1),
+   

[PATCH net-next v6 08/11] bpf: Add a Landlock sandbox example

2017-03-28 Thread Mickaël Salaün
Add a basic sandbox tool to create a process isolated from some part of
the system. This sandbox create a read-only environment. It is only
allowed to write to a character device such as a TTY:

  # :> X
  # echo $?
  0
  # ./samples/bpf/landlock1 /bin/sh -i
  Launching a new sandboxed process.
  # :> Y
  cannot create Y: Operation not permitted

Changes since v5:
* cosmetic fixes
* rebase

Changes since v4:
* write Landlock rule in C and compiled it with LLVM
* remove cgroup handling
* remove path handling: only handle a read-only environment
* remove errno return codes

Changes since v3:
* remove seccomp and origin field: completely free from seccomp programs
* handle more FS-related hooks
* handle inode hooks and directory traversal
* add faked but consistent view thanks to ENOENT
* add /lib64 in the example
* fix spelling
* rename some types and definitions (e.g. SECCOMP_ADD_LANDLOCK_RULE)

Changes since v2:
* use BPF_PROG_ATTACH for cgroup handling

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---
 samples/bpf/Makefile |   4 ++
 samples/bpf/bpf_load.c   |  31 +++--
 samples/bpf/landlock1_kern.c |  46 +++
 samples/bpf/landlock1_user.c | 102 +++
 4 files changed, 179 insertions(+), 4 deletions(-)
 create mode 100644 samples/bpf/landlock1_kern.c
 create mode 100644 samples/bpf/landlock1_user.c

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index d42b495b0992..4743674a3fa3 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -36,6 +36,7 @@ hostprogs-y += lwt_len_hist
 hostprogs-y += xdp_tx_iptunnel
 hostprogs-y += test_map_in_map
 hostprogs-y += per_socket_stats_example
+hostprogs-y += landlock1
 
 # Libbpf dependencies
 LIBBPF := ../../tools/lib/bpf/bpf.o
@@ -76,6 +77,7 @@ lwt_len_hist-objs := bpf_load.o $(LIBBPF) lwt_len_hist_user.o
 xdp_tx_iptunnel-objs := bpf_load.o $(LIBBPF) xdp_tx_iptunnel_user.o
 test_map_in_map-objs := bpf_load.o $(LIBBPF) test_map_in_map_user.o
 per_socket_stats_example-objs := $(LIBBPF) cookie_uid_helper_example.o
+landlock1-objs := bpf_load.o $(LIBBPF) landlock1_user.o
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
@@ -111,6 +113,7 @@ always += lwt_len_hist_kern.o
 always += xdp_tx_iptunnel_kern.o
 always += test_map_in_map_kern.o
 always += cookie_uid_helper_example.o
+always += landlock1_kern.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 HOSTCFLAGS += -I$(srctree)/tools/lib/
@@ -146,6 +149,7 @@ HOSTLOADLIBES_tc_l2_redirect += -l elf
 HOSTLOADLIBES_lwt_len_hist += -l elf
 HOSTLOADLIBES_xdp_tx_iptunnel += -lelf
 HOSTLOADLIBES_test_map_in_map += -lelf
+HOSTLOADLIBES_landlock1 += -lelf
 
 # Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on 
cmdline:
 #  make samples/bpf/ LLC=~/git/llvm/build/bin/llc 
CLANG=~/git/llvm/build/bin/clang
diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index 4a3460d7c01f..3713e5e2e998 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -29,6 +29,8 @@
 
 static char license[128];
 static int kern_version;
+static union bpf_prog_subtype subtype = {};
+static bool has_subtype;
 static bool processed_sec[128];
 char bpf_log_buf[BPF_LOG_BUF_SIZE];
 int map_fd[MAX_MAPS];
@@ -68,6 +70,7 @@ static int load_and_attach(const char *event, struct bpf_insn 
*prog, int size)
bool is_perf_event = strncmp(event, "perf_event", 10) == 0;
bool is_cgroup_skb = strncmp(event, "cgroup/skb", 10) == 0;
bool is_cgroup_sk = strncmp(event, "cgroup/sock", 11) == 0;
+   bool is_landlock = strncmp(event, "landlock", 8) == 0;
size_t insns_cnt = size / sizeof(struct bpf_insn);
enum bpf_prog_type prog_type;
char buf[256];
@@ -94,6 +97,13 @@ static int load_and_attach(const char *event, struct 
bpf_insn *prog, int size)
prog_type = BPF_PROG_TYPE_CGROUP_SKB;
} else if (is_cgroup_sk) {
prog_type = BPF_PROG_TYPE_CGROUP_SOCK;
+   } else if (is_landlock) {
+   prog_type = BPF_PROG_TYPE_LANDLOCK;
+   if (!has_subtype) {
+   printf("No subtype\n");
+   return -1;
+   }
+   st = 
} else {
printf("Unknown event '%s'\n", event);
return -1;
@@ -108,7 +118,8 @@ static int load_and_attach(const char *event, struct 
bpf_insn *prog, int size)
 
prog_fd[prog_cnt++] = fd;
 
-   if (is_xdp || is_perf_event || is_cgroup_skb || is_cgroup_sk)
+   if (is_xdp || is_perf_event || is_cgroup_skb || is_

[PATCH net-next v6 05/11] seccomp: Split put_seccomp_filter() with put_seccomp()

2017-03-28 Thread Mickaël Salaün
The semantic is unchanged. This will be useful for the Landlock
integration with seccomp (next commit).

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Will Drewry <w...@chromium.org>
---
 include/linux/seccomp.h |  4 ++--
 kernel/fork.c   |  2 +-
 kernel/seccomp.c| 18 +-
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index ecc296c137cd..e25aee2cdfc0 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -77,10 +77,10 @@ static inline int seccomp_mode(struct seccomp *s)
 #endif /* CONFIG_SECCOMP */
 
 #ifdef CONFIG_SECCOMP_FILTER
-extern void put_seccomp_filter(struct task_struct *tsk);
+extern void put_seccomp(struct task_struct *tsk);
 extern void get_seccomp_filter(struct task_struct *tsk);
 #else  /* CONFIG_SECCOMP_FILTER */
-static inline void put_seccomp_filter(struct task_struct *tsk)
+static inline void put_seccomp(struct task_struct *tsk)
 {
return;
 }
diff --git a/kernel/fork.c b/kernel/fork.c
index 6c463c80e93d..a27d8e67ce33 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -363,7 +363,7 @@ void free_task(struct task_struct *tsk)
 #endif
rt_mutex_debug_task_free(tsk);
ftrace_graph_exit_task(tsk);
-   put_seccomp_filter(tsk);
+   put_seccomp(tsk);
arch_release_task_struct(tsk);
if (tsk->flags & PF_KTHREAD)
free_kthread_struct(tsk);
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 65f61077ad50..326f79e32127 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -64,6 +64,8 @@ struct seccomp_filter {
 /* Limit any path through the tree to 256KB worth of instructions. */
 #define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
 
+static void put_seccomp_filter(struct seccomp_filter *filter);
+
 /*
  * Endianness is explicitly ignored and left for BPF program authors to manage
  * as per the specific architecture.
@@ -314,7 +316,7 @@ static inline void seccomp_sync_threads(void)
 * current's path will hold a reference.  (This also
 * allows a put before the assignment.)
 */
-   put_seccomp_filter(thread);
+   put_seccomp_filter(thread->seccomp.filter);
smp_store_release(>seccomp.filter,
  caller->seccomp.filter);
 
@@ -476,10 +478,11 @@ static inline void seccomp_filter_free(struct 
seccomp_filter *filter)
}
 }
 
-/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */
-void put_seccomp_filter(struct task_struct *tsk)
+/* put_seccomp_filter - decrements the ref count of a filter */
+static void put_seccomp_filter(struct seccomp_filter *filter)
 {
-   struct seccomp_filter *orig = tsk->seccomp.filter;
+   struct seccomp_filter *orig = filter;
+
/* Clean up single-reference branches iteratively. */
while (orig && atomic_dec_and_test(>usage)) {
struct seccomp_filter *freeme = orig;
@@ -488,6 +491,11 @@ void put_seccomp_filter(struct task_struct *tsk)
}
 }
 
+void put_seccomp(struct task_struct *tsk)
+{
+   put_seccomp_filter(tsk->seccomp.filter);
+}
+
 static void seccomp_init_siginfo(siginfo_t *info, int syscall, int reason)
 {
memset(info, 0, sizeof(*info));
@@ -914,7 +922,7 @@ long seccomp_get_filter(struct task_struct *task, unsigned 
long filter_off,
if (copy_to_user(data, fprog->filter, bpf_classic_proglen(fprog)))
ret = -EFAULT;
 
-   put_seccomp_filter(task);
+   put_seccomp_filter(task->seccomp.filter);
return ret;
 
 out:
-- 
2.11.0



[PATCH net-next v6 07/11] landlock: Add ptrace restrictions

2017-03-28 Thread Mickaël Salaün
A landlocked process has less privileges than a non-landlocked process
and must then be subject to additional restrictions when manipulating
processes. To be allowed to use ptrace(2) and related syscalls on a
target process, a landlocked process must have a subset of the target
process' rules.

New in v6

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---
 security/landlock/Makefile   |   2 +-
 security/landlock/hooks_ptrace.c | 126 +++
 security/landlock/hooks_ptrace.h |  11 
 security/landlock/init.c |   2 +
 4 files changed, 140 insertions(+), 1 deletion(-)
 create mode 100644 security/landlock/hooks_ptrace.c
 create mode 100644 security/landlock/hooks_ptrace.h

diff --git a/security/landlock/Makefile b/security/landlock/Makefile
index da8ba8b5183e..099a56ca4842 100644
--- a/security/landlock/Makefile
+++ b/security/landlock/Makefile
@@ -2,4 +2,4 @@ ccflags-$(CONFIG_SECURITY_LANDLOCK) += -Werror=unused-function
 
 obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o
 
-landlock-y := init.o providers.o hooks.o hooks_fs.o
+landlock-y := init.o providers.o hooks.o hooks_fs.o hooks_ptrace.o
diff --git a/security/landlock/hooks_ptrace.c b/security/landlock/hooks_ptrace.c
new file mode 100644
index ..8ab53baba9ad
--- /dev/null
+++ b/security/landlock/hooks_ptrace.c
@@ -0,0 +1,126 @@
+/*
+ * Landlock LSM - ptrace hooks
+ *
+ * Copyright © 2017 Mickaël Salaün <m...@digikod.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include  /* ARRAY_SIZE */
+#include  /* struct landlock_events */
+#include 
+#include  /* struct task_struct */
+#include 
+
+#include "hooks.h" /* landlocked() */
+
+#include "hooks_ptrace.h"
+
+
+static bool landlock_events_are_subset(const struct landlock_events *parent,
+   const struct landlock_events *child)
+{
+   size_t i;
+
+   if (!parent || !child)
+   return false;
+   if (parent == child)
+   return true;
+
+   for (i = 0; i < ARRAY_SIZE(child->rules); i++) {
+   struct landlock_rule *walker;
+   bool found_parent = false;
+
+   if (!parent->rules[i])
+   continue;
+   for (walker = child->rules[i]; walker; walker = walker->prev) {
+   if (walker == parent->rules[i]) {
+   found_parent = true;
+   break;
+   }
+   }
+   if (!found_parent)
+   return false;
+   }
+   return true;
+}
+
+static bool landlock_task_has_subset_events(const struct task_struct *parent,
+   const struct task_struct *child)
+{
+#ifdef CONFIG_SECCOMP_FILTER
+   if (landlock_events_are_subset(parent->seccomp.landlock_events,
+   child->seccomp.landlock_events))
+   /* must be ANDed with other providers (i.e. cgroup) */
+   return true;
+#endif /* CONFIG_SECCOMP_FILTER */
+   return false;
+}
+
+/**
+ * landlock_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 has Landlock rules, then the child must have at least
+ * the same rules.  Else denied.
+ *
+ * Determine whether a process may access another, returning 0 if permission
+ * granted, -errno if denied.
+ */
+static int landlock_ptrace_access_check(struct task_struct *child,
+   unsigned int mode)
+{
+   if (!landlocked(current))
+   return 0;
+
+   if (!landlocked(child))
+   return -EPERM;
+
+   if (landlock_task_has_subset_events(current, child))
+   return 0;
+
+   return -EPERM;
+}
+
+/**
+ * landlock_ptrace_traceme - determine whether another process may trace the
+ *  current one
+ *
+ * @parent: the task proposed to be the tracer
+ *
+ * If the parent has Landlock rules, then the current task must have the same
+ * or more rules.
+ * Else denied.
+ *
+ * Determine whether the nominated task is permitted to trace the current
+ * process, returning 0 if permission is granted, -errno if denied.
+ */
+static int landlock_ptrace_traceme(struct task_struct *parent)
+{
+   if (!landlocked(parent))
+   return 0;
+
+   if (!landlocked(curr

[PATCH net-next v6 04/11] landlock: Add LSM hooks related to filesystem

2017-03-28 Thread Mickaël Salaün
Handle 33 filesystem-related LSM hooks for the Landlock filesystem
event: LANDLOCK_SUBTYPE_EVENT_FS.

A Landlock event wrap LSM hooks for similar kernel object types (e.g.
struct file, struct path...). Multiple LSM hooks can trigger the same
Landlock event.

Landlock handle nine coarse-grained actions: read, write, execute, new,
get, remove, ioctl, lock and fcntl. Each of them abstract LSM hook
access control in a way that can be extended in the future.

The Landlock LSM hook registration is done after other LSM to only run
actions from user-space, via eBPF programs, if the access was granted by
major (privileged) LSMs.

Changes since v5:
* split hooks.[ch] into hooks.[ch] and hooks_fs.[ch]
* add more documentation
* cosmetic fixes

Changes since v4:
* add LSM hook abstraction called Landlock event
  * use the compiler type checking to verify hooks use by an event
  * handle all filesystem related LSM hooks (e.g. file_permission,
mmap_file, sb_mount...)
* register BPF programs for Landlock just after LSM hooks registration
* move hooks registration after other LSMs
* add failsafes to check if a hook is not used by the kernel
* allow partial raw value access form the context (needed for programs
  generated by LLVM)

Changes since v3:
* split commit
* add hooks dealing with struct inode and struct path pointers:
  inode_permission and inode_getattr
* add abstraction over eBPF helper arguments thanks to wrapping structs

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---
 include/linux/lsm_hooks.h|   5 +
 security/landlock/Makefile   |   4 +-
 security/landlock/hooks.c| 115 +
 security/landlock/hooks.h| 177 ++
 security/landlock/hooks_fs.c | 563 +++
 security/landlock/hooks_fs.h |  19 ++
 security/landlock/init.c |  13 +
 security/security.c  |   7 +-
 8 files changed, 901 insertions(+), 2 deletions(-)
 create mode 100644 security/landlock/hooks.c
 create mode 100644 security/landlock/hooks.h
 create mode 100644 security/landlock/hooks_fs.c
 create mode 100644 security/landlock/hooks_fs.h

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index e29d4c62a3c8..884289166a0e 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1920,5 +1920,10 @@ void __init loadpin_add_hooks(void);
 #else
 static inline void loadpin_add_hooks(void) { };
 #endif
+#ifdef CONFIG_SECURITY_LANDLOCK
+extern void __init landlock_add_hooks(void);
+#else
+static inline void __init landlock_add_hooks(void) { }
+#endif /* CONFIG_SECURITY_LANDLOCK */
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/security/landlock/Makefile b/security/landlock/Makefile
index 7205f9a7a2ee..c0db504a6335 100644
--- a/security/landlock/Makefile
+++ b/security/landlock/Makefile
@@ -1,3 +1,5 @@
+ccflags-$(CONFIG_SECURITY_LANDLOCK) += -Werror=unused-function
+
 obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o
 
-landlock-y := init.o
+landlock-y := init.o hooks.o hooks_fs.o
diff --git a/security/landlock/hooks.c b/security/landlock/hooks.c
new file mode 100644
index ..eaee8162ff70
--- /dev/null
+++ b/security/landlock/hooks.c
@@ -0,0 +1,115 @@
+/*
+ * Landlock LSM - hooks helpers
+ *
+ * Copyright © 2017 Mickaël Salaün <m...@digikod.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include  /* task_pt_regs() */
+#include  /* syscall_get_nr(), syscall_get_arch() */
+#include  /* enum bpf_access_type, struct landlock_context */
+#include  /* EPERM */
+#include  /* BPF_PROG_RUN() */
+#include  /* struct landlock_rule */
+#include 
+#include  /* list_add_tail_rcu */
+#include  /* offsetof */
+
+#include "common.h" /* get_index() */
+#include "hooks.h" /* CTX_ARG_NB */
+
+
+__init void landlock_register_hooks(struct security_hook_list *hooks, int 
count)
+{
+   int i;
+
+   for (i = 0; i < count; i++) {
+   hooks[i].lsm = "landlock";
+   list_add_tail_rcu([i].list, hooks[i].head);
+   }
+}
+
+bool landlock_is_valid_access(int off, int size, enum bpf_access_type type,
+   enum bpf_reg_type *reg_type,
+   enum bpf_reg_type ctx_types[CTX_ARG_NB],
+   union bpf_prog_subtype *prog_subtype)
+{
+   int max_size;
+
+   if (type != BPF_READ)
+   return false;
+   if (off < 0 || off >= sizeof(struct landlock_context))
+   return false;
+   if (size <= 0 || size > sizeof(__u64))
+   

Re: [kernel-hardening] [PATCH v5 06/10] seccomp,landlock: Handle Landlock events per process hierarchy

2017-03-02 Thread Mickaël Salaün


On 02/03/2017 11:22, Djalal Harouni wrote:
> On Wed, Feb 22, 2017 at 2:26 AM, Mickaël Salaün <m...@digikod.net> wrote:
>> The seccomp(2) syscall can be use to apply a Landlock rule to the
>> current process. As with a seccomp filter, the Landlock rule is enforced
>> for all its future children. An inherited rule tree can be updated
>> (append-only) by the owner of inherited Landlock nodes (e.g. a parent
>> process that create a new rule). However, an intermediate task, which
>> did not create a rule, will not be able to update its children's rules.
>>
>> Landlock rules can be tied to a Landlock event. When such an event is
>> triggered, a tree of rules can be evaluated. Thisk kind of tree is
>> created with a first node.  This node reference a list of rules and an
>> optional parent node. Each rule return a 32-bit value which can
>> interrupt the evaluation with a non-zero value. If every rules returned
>> zero, the evaluation continues with the rule list of the parent node,
>> until the end of the tree.
>>
>> Changes since v4:
>> * merge manager and seccomp patches
>> * return -EFAULT in seccomp(2) when user_bpf_fd is null to easely check
>>   if Landlock is supported
>> * only allow a process with the global CAP_SYS_ADMIN to use Landlock
>>   (will be lifted in the future)
>> * add an early check to exit as soon as possible if the current process
>>   does not have Landlock rules
>>
>> Changes since v3:
>> * remove the hard link with seccomp (suggested by Andy Lutomirski and
>>   Kees Cook):
>>   * remove the cookie which could imply multiple evaluation of Landlock
>> rules
>>   * remove the origin field in struct landlock_data
>> * remove documentation fix (merged upstream)
>> * rename the new seccomp command to SECCOMP_ADD_LANDLOCK_RULE
>> * internal renaming
>> * split commit
>> * new design to be able to inherit on the fly the parent rules
>>
>> Changes since v2:
>> * Landlock programs can now be run without seccomp filter but for any
>>   syscall (from the process) or interruption
>> * move Landlock related functions and structs into security/landlock/*
>>   (to manage cgroups as well)
>> * fix seccomp filter handling: run Landlock programs for each of their
>>   legitimate seccomp filter
>> * properly clean up all seccomp results
>> * cosmetic changes to ease the understanding
>> * fix some ifdef
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>> Cc: Alexei Starovoitov <a...@kernel.org>
>> Cc: Andrew Morton <a...@linux-foundation.org>
>> Cc: Andy Lutomirski <l...@amacapital.net>
>> Cc: James Morris <james.l.mor...@oracle.com>
>> Cc: Kees Cook <keesc...@chromium.org>
>> Cc: Serge E. Hallyn <se...@hallyn.com>
>> Cc: Will Drewry <w...@chromium.org>
>> ---
>>  include/linux/seccomp.h  |   8 ++
>>  include/uapi/linux/seccomp.h |   1 +
>>  kernel/fork.c|  14 +-
>>  kernel/seccomp.c |   8 ++
>>  security/landlock/Makefile   |   2 +-
>>  security/landlock/hooks.c|  42 +-
>>  security/landlock/manager.c  | 321 
>> +++
>>  7 files changed, 392 insertions(+), 4 deletions(-)
>>  create mode 100644 security/landlock/manager.c
>>
>> diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
>> index e25aee2cdfc0..9a38de3c0e72 100644
>> --- a/include/linux/seccomp.h
>> +++ b/include/linux/seccomp.h
>> @@ -10,6 +10,10 @@
>>  #include 
>>  #include 
>>
>> +#if defined(CONFIG_SECCOMP_FILTER) && defined(CONFIG_SECURITY_LANDLOCK)
>> +struct landlock_events;
>> +#endif /* CONFIG_SECCOMP_FILTER && CONFIG_SECURITY_LANDLOCK */
>> +
>>  struct seccomp_filter;
>>  /**
>>   * struct seccomp - the state of a seccomp'ed process
>> @@ -18,6 +22,7 @@ struct seccomp_filter;
>>   * system calls available to a process.
>>   * @filter: must always point to a valid seccomp-filter or NULL as it is
>>   *  accessed without locking during system call entry.
>> + * @landlock_events: contains an array of Landlock rules.
>>   *
>>   *  @filter must only be accessed from the context of current as 
>> there
>>   *  is no read locking.
>> @@ -25,6 +30,9 @@ struct seccomp_filter;
>>  struct seccomp {
>> int mode;
>> struct seccomp_filter *filter;
>> +#if defined(CONFIG_SECCOMP_FILTER) && defined(CONFIG_SECURITY_LANDLOCK)
>> +   struct landlock_e

Re: [PATCH v5 06/10] seccomp,landlock: Handle Landlock events per process hierarchy

2017-03-02 Thread Mickaël Salaün


On 03/03/2017 01:55, Andy Lutomirski wrote:
> On Thu, Mar 2, 2017 at 4:48 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>
>> On 02/03/2017 17:36, Andy Lutomirski wrote:
>>> On Wed, Mar 1, 2017 at 3:28 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>>>
>>>>
>>>> On 01/03/2017 23:20, Andy Lutomirski wrote:
>>>>> On Wed, Mar 1, 2017 at 2:14 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>>>>>
>>>>>> On 28/02/2017 21:01, Andy Lutomirski wrote:
>>>>>>> On Tue, Feb 21, 2017 at 5:26 PM, Mickaël Salaün <m...@digikod.net> 
>>>>>>> wrote:
>>>>>> This design makes it possible for a process to add more constraints to
>>>>>> its children on the fly. I think it is a good feature to have and a
>>>>>> safer default inheritance mechanism, but it could be guarded by an
>>>>>> option flag if we want both mechanism to be available. The same design
>>>>>> could be used by seccomp filter too.
>>>>>>
>>>>>
>>>>> Then let's do it right.
>>>>>
>>>>> Currently each task has an array of seccomp filter layers.  When a
>>>>> task forks, the child inherits the layers.  All the layers are
>>>>> presently immutable.  With Landlock, a layer can logically be a
>>>>> syscall fitler layer or a Landlock layer.  This fits in to the
>>>>> existing model just fine.
>>>>>
>>>>> If we want to have an interface to allow modification of an existing
>>>>> layer, let's make it so that, when a layer is added, you have to
>>>>> specify a flag to make the layer modifiable (by current, presumably,
>>>>> although I can imagine other policies down the road).  Then have a
>>>>> separate API that modifies a layer.
>>>>>
>>>>> IOW, I think your patch is bad for three reasons, all fixable:
>>>>>
>>>>> 1. The default is wrong.  A layer should be immutable to avoid an easy
>>>>> attack in which you try to sandbox *yourself* and then you just modify
>>>>> the layer to weaken it.
>>>>
>>>> This is not possible, there is only an operation for now:
>>>> SECCOMP_ADD_LANDLOCK_RULE. You can only add more rules to the list (as
>>>> for seccomp filter). There is no way to weaken a sandbox. The question
>>>> is: how do we want to handle the rules *tree* (from the kernel point of
>>>> view)?
>>>>
>>>
>>> Fair enough.  But I still think that immutability (like regular
>>> seccomp) should be the default.  For security, simplicity is
>>> important.  I guess there could be two ways to relax immutability:
>>> allowing making the layer stricter and allowing any change at all.
>>>
>>> As a default, though, programs should be able to expect that:
>>>
>>> seccomp(SECCOMP_ADD_WHATEVER, ...);
>>> fork();
>>>
>>> [parent gets compromised]
>>> [in parent]seccomp(anything whatsoever);
>>>
>>> will not affect the child,  If the parent wants to relax that, that's
>>> fine, but I think it should be explicit.
>>
>> Good point. However the term "immutability" doesn't fit right because
>> the process is still allowed to add more rules to itself (as for
>> seccomp). The difference lays in the way a rule may be "appended" (by
>> the current process) or "inserted" (by a parent process).
>>
>> I think three or four kind of operations (through the seccomp syscall)
>> make sense:
>> * append a rule (for the current process and its future children)
> 
> Sure, but this operation should *never* affect existing children,
> existing seccomp layers, existing nodes, etc.  It should affect
> current and future children only.  Or it could simply not exist for
> Landlock and instead you'd have to add a layer (see below) and then
> program that layer.
> 
>> * add a node (insert point), from which the inserted rules will be tied
>> * insert a rule in the node, which will be inherited by futures children
> 
> I would advocate calling this a "seccomp layer" and making creation
> and manipulation of them generic.
> 
>> * (maybe a "lock" command to make a layer immutable for the current
>> process and its children)
> 
> Hmm, maybe.
> 
>>
>> Doing so, a process is only allowed to insert a rule if a node was
>> previously added.

Re: [PATCH v5 06/10] seccomp,landlock: Handle Landlock events per process hierarchy

2017-03-02 Thread Mickaël Salaün

On 02/03/2017 17:36, Andy Lutomirski wrote:
> On Wed, Mar 1, 2017 at 3:28 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>
>>
>> On 01/03/2017 23:20, Andy Lutomirski wrote:
>>> On Wed, Mar 1, 2017 at 2:14 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>>>
>>>> On 28/02/2017 21:01, Andy Lutomirski wrote:
>>>>> On Tue, Feb 21, 2017 at 5:26 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>>> This design makes it possible for a process to add more constraints to
>>>> its children on the fly. I think it is a good feature to have and a
>>>> safer default inheritance mechanism, but it could be guarded by an
>>>> option flag if we want both mechanism to be available. The same design
>>>> could be used by seccomp filter too.
>>>>
>>>
>>> Then let's do it right.
>>>
>>> Currently each task has an array of seccomp filter layers.  When a
>>> task forks, the child inherits the layers.  All the layers are
>>> presently immutable.  With Landlock, a layer can logically be a
>>> syscall fitler layer or a Landlock layer.  This fits in to the
>>> existing model just fine.
>>>
>>> If we want to have an interface to allow modification of an existing
>>> layer, let's make it so that, when a layer is added, you have to
>>> specify a flag to make the layer modifiable (by current, presumably,
>>> although I can imagine other policies down the road).  Then have a
>>> separate API that modifies a layer.
>>>
>>> IOW, I think your patch is bad for three reasons, all fixable:
>>>
>>> 1. The default is wrong.  A layer should be immutable to avoid an easy
>>> attack in which you try to sandbox *yourself* and then you just modify
>>> the layer to weaken it.
>>
>> This is not possible, there is only an operation for now:
>> SECCOMP_ADD_LANDLOCK_RULE. You can only add more rules to the list (as
>> for seccomp filter). There is no way to weaken a sandbox. The question
>> is: how do we want to handle the rules *tree* (from the kernel point of
>> view)?
>>
> 
> Fair enough.  But I still think that immutability (like regular
> seccomp) should be the default.  For security, simplicity is
> important.  I guess there could be two ways to relax immutability:
> allowing making the layer stricter and allowing any change at all.
> 
> As a default, though, programs should be able to expect that:
> 
> seccomp(SECCOMP_ADD_WHATEVER, ...);
> fork();
> 
> [parent gets compromised]
> [in parent]seccomp(anything whatsoever);
> 
> will not affect the child,  If the parent wants to relax that, that's
> fine, but I think it should be explicit.

Good point. However the term "immutability" doesn't fit right because
the process is still allowed to add more rules to itself (as for
seccomp). The difference lays in the way a rule may be "appended" (by
the current process) or "inserted" (by a parent process).

I think three or four kind of operations (through the seccomp syscall)
make sense:
* append a rule (for the current process and its future children)
* add a node (insert point), from which the inserted rules will be tied
* insert a rule in the node, which will be inherited by futures children
* (maybe a "lock" command to make a layer immutable for the current
process and its children)

Doing so, a process is only allowed to insert a rule if a node was
previously added. To forbid itself to insert new rules to one of its
children, a process just need to not add a node before forking. Like
this, there is no need for special rule flags nor default behavior,
everything is explicit.

For this series, I will stick to the same behavior as seccomp filter:
only append rules to the current process (and its future children).


>>> 2. The API that adds a layer should be different from the API that
>>> modifies a layer.
>>
>> Right, but it doesn't apply now because we can only add rules.
> 
> That's not what the code appears to do, though.  Sometimes it makes a
> new layer without modifying tasks that share the layer and sometimes
> it modifies the layer.
> 
> Both operations are probably okay, but they're not the same operation
> and they shouldn't pretend to be.

It should be OK with my previous proposal. The other details could be
discussed in a separate future patch series.


>>> 3. The whole modification mechanism should be a separate patch to be
>>> reviewed on its own merits.
>>
>> For a rule *replacement*, sure!
> 
> And for modification of policy for non-current tasks.  That's a big
> departure from normal seccomp and should be reviewed as such.

Agreed



signature.asc
Description: OpenPGP digital signature


Re: [PATCH v5 06/10] seccomp,landlock: Handle Landlock events per process hierarchy

2017-03-01 Thread Mickaël Salaün


On 01/03/2017 23:20, Andy Lutomirski wrote:
> On Wed, Mar 1, 2017 at 2:14 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>
>> On 28/02/2017 21:01, Andy Lutomirski wrote:
>>> On Tue, Feb 21, 2017 at 5:26 PM, Mickaël Salaün <m...@digikod.net> wrote:
>>>> The seccomp(2) syscall can be use to apply a Landlock rule to the
>>>> current process. As with a seccomp filter, the Landlock rule is enforced
>>>> for all its future children. An inherited rule tree can be updated
>>>> (append-only) by the owner of inherited Landlock nodes (e.g. a parent
>>>> process that create a new rule)
>>>
>>> Can you clarify exaclty what this type of update does?  Is it
>>> something that should be supported by normal seccomp rules as well?
>>
>> There is two main structures involved here: struct landlock_node and
>> struct landlock_rule, both defined in include/linux/landlock.h [02/10].
>>
>> Let's take an example with seccomp filter and then Landlock:
>> * seccomp filter: Process P1 creates and applies a seccomp filter F1 to
>> itself. Then it forks and creates a child P2, which inherits P1's
>> filters, hence F1. Now, if P1 add a new seccomp filter F2 to itself, P2
>> *won't get it*. The P2's filter list will still only contains F1 but not
>> F2. If P2 sets up and applies a new filter F3 to itself, its filter list
>> will contains F1 and F3.
>> * Landlock: Process P1 creates and applies a Landlock rule R1 to itself.
>> Underneath the kernel creates a new node N1 dedicated to P1, which
>> contains all its rules. Then P1 forks and creates a child P2, which
>> inherits P1's rules, hence R1. Underneath P2 inherited N1. Now, if P1
>> add a new Landlock rule R2 to itself, P2 *will get it* as well (because
>> R2 is part of N1). If P2 creates and applies a new rule R3 to itself,
>> its rules will contains R1, R2 and R3. Underneath the kernel created a
>> new node N2 for P2, which only contains R3 but inherits/links to N1.
>>
>> This design makes it possible for a process to add more constraints to
>> its children on the fly. I think it is a good feature to have and a
>> safer default inheritance mechanism, but it could be guarded by an
>> option flag if we want both mechanism to be available. The same design
>> could be used by seccomp filter too.
>>
> 
> Then let's do it right.
> 
> Currently each task has an array of seccomp filter layers.  When a
> task forks, the child inherits the layers.  All the layers are
> presently immutable.  With Landlock, a layer can logically be a
> syscall fitler layer or a Landlock layer.  This fits in to the
> existing model just fine.
> 
> If we want to have an interface to allow modification of an existing
> layer, let's make it so that, when a layer is added, you have to
> specify a flag to make the layer modifiable (by current, presumably,
> although I can imagine other policies down the road).  Then have a
> separate API that modifies a layer.
> 
> IOW, I think your patch is bad for three reasons, all fixable:
> 
> 1. The default is wrong.  A layer should be immutable to avoid an easy
> attack in which you try to sandbox *yourself* and then you just modify
> the layer to weaken it.

This is not possible, there is only an operation for now:
SECCOMP_ADD_LANDLOCK_RULE. You can only add more rules to the list (as
for seccomp filter). There is no way to weaken a sandbox. The question
is: how do we want to handle the rules *tree* (from the kernel point of
view)?

> 
> 2. The API that adds a layer should be different from the API that
> modifies a layer.

Right, but it doesn't apply now because we can only add rules.

> 
> 3. The whole modification mechanism should be a separate patch to be
> reviewed on its own merits.

For a rule *replacement*, sure!

> 
>> The current inheritance mechanism doesn't enable to only add a rule to
>> the current process. The rule will be inherited by its children
>> (starting from the children created after the first applied rule). An
>> option flag NEW_RULE_HIERARCHY (or maybe another seccomp operation)
>> could enable to create a new node for the current process, and then
>> makes it not inherited by the previous children.
> 
> I like my proposal above much better.  "Add a layer" and "change a
> layer" should be different operations.

I agree, but for now it's about how to handle immutable (but growing)
inherited rules.



signature.asc
Description: OpenPGP digital signature


Re: [PATCH v5 03/10] bpf: Define handle_fs and add a new helper bpf_handle_fs_get_mode()

2017-03-01 Thread Mickaël Salaün

On 01/03/2017 10:32, James Morris wrote:
> On Wed, 22 Feb 2017, Mickaël Salaün wrote:
> 
>> Add an eBPF function bpf_handle_fs_get_mode(handle_fs) to get the mode
>> of a an abstract object wrapping either a file, a dentry, a path, or an
>> inode.
>>
>> Changes since v4:
>> * use a file abstraction (handle) to wrap inode, dentry, path and file
>>   structs
> 
> Good to see these abstractions.  As discussed at LPC, we need to ensure 
> that we don't couple the Landlock API too closely with the LSM API, as the 
> former is an ABI exposed to userland -- we don't want to lose the ability 
> to change LSM internally due to breaking Landlock policies.

Right, it is the case now, especially with the Landlock events.

> 
>> @@ -82,6 +87,8 @@ enum bpf_arg_type {
>>  
>>  ARG_PTR_TO_CTX, /* pointer to context */
>>  ARG_ANYTHING,   /* any (initialized) argument is ok */
>> +
>> +ARG_CONST_PTR_TO_HANDLE_FS, /* pointer to an abstract FS struct */
>>  };
> 
> Extraneous whitespace?

It is on purpose, following the same rules as used for this enum.

 Mickaël



signature.asc
Description: OpenPGP digital signature


Re: [PATCH v5 06/10] seccomp,landlock: Handle Landlock events per process hierarchy

2017-03-01 Thread Mickaël Salaün

On 28/02/2017 21:01, Andy Lutomirski wrote:
> On Tue, Feb 21, 2017 at 5:26 PM, Mickaël Salaün <m...@digikod.net> wrote:
>> The seccomp(2) syscall can be use to apply a Landlock rule to the
>> current process. As with a seccomp filter, the Landlock rule is enforced
>> for all its future children. An inherited rule tree can be updated
>> (append-only) by the owner of inherited Landlock nodes (e.g. a parent
>> process that create a new rule)
> 
> Can you clarify exaclty what this type of update does?  Is it
> something that should be supported by normal seccomp rules as well?

There is two main structures involved here: struct landlock_node and
struct landlock_rule, both defined in include/linux/landlock.h [02/10].

Let's take an example with seccomp filter and then Landlock:
* seccomp filter: Process P1 creates and applies a seccomp filter F1 to
itself. Then it forks and creates a child P2, which inherits P1's
filters, hence F1. Now, if P1 add a new seccomp filter F2 to itself, P2
*won't get it*. The P2's filter list will still only contains F1 but not
F2. If P2 sets up and applies a new filter F3 to itself, its filter list
will contains F1 and F3.
* Landlock: Process P1 creates and applies a Landlock rule R1 to itself.
Underneath the kernel creates a new node N1 dedicated to P1, which
contains all its rules. Then P1 forks and creates a child P2, which
inherits P1's rules, hence R1. Underneath P2 inherited N1. Now, if P1
add a new Landlock rule R2 to itself, P2 *will get it* as well (because
R2 is part of N1). If P2 creates and applies a new rule R3 to itself,
its rules will contains R1, R2 and R3. Underneath the kernel created a
new node N2 for P2, which only contains R3 but inherits/links to N1.

This design makes it possible for a process to add more constraints to
its children on the fly. I think it is a good feature to have and a
safer default inheritance mechanism, but it could be guarded by an
option flag if we want both mechanism to be available. The same design
could be used by seccomp filter too.


> 
>> +/**
>> + * landlock_run_prog - run Landlock program for a syscall
> 
> Unless this is actually specific to syscalls, s/for a syscall//, perhaps?

Right, not specific to syscall anymore.

> 
>> +   if (new_events->nodes[event_idx]->owner ==
>> +   _events->nodes[event_idx]) {
>> +   /* We are the owner, we can then update the node. */
>> +   add_landlock_rule(new_events, rule);
> 
> This is the part I don't get.  Adding a rule if you're the owner (BTW,
> why is ownership visible to userspace at all?) for just yourself and
> future children is very different from adding it so it applies to
> preexisting children too.

Node ownership is not (directly) visible to userspace.

The current inheritance mechanism doesn't enable to only add a rule to
the current process. The rule will be inherited by its children
(starting from the children created after the first applied rule). An
option flag NEW_RULE_HIERARCHY (or maybe another seccomp operation)
could enable to create a new node for the current process, and then
makes it not inherited by the previous children.


> 
> 
>> +   } else if (atomic_read(_events->usage) == 1) {
>> +   WARN_ON(new_events->nodes[event_idx]->owner);
>> +   /*
>> +* We can become the new owner if no other task use 
>> it.
>> +* This avoid an unnecessary allocation.
>> +*/
>> +   new_events->nodes[event_idx]->owner =
>> +   _events->nodes[event_idx];
>> +   add_landlock_rule(new_events, rule);
>> +   } else {
>> +   /*
>> +* We are not the owner, we need to fork 
>> current_events
>> +* and then add a new node.
>> +*/
>> +   struct landlock_node *node;
>> +   size_t i;
>> +
>> +   node = kmalloc(sizeof(*node), GFP_KERNEL);
>> +   if (!node) {
>> +   new_events = ERR_PTR(-ENOMEM);
>> +   goto put_rule;
>> +   }
>> +   atomic_set(>usage, 1);
>> +   /* set the previous node after the new_events
>> +* allocation */
>> +   node->prev = NULL;
>> +   /* do not increment the previous node usage */
>> +  

Re: [PATCH v5 07/10] bpf: Add a Landlock sandbox example

2017-02-23 Thread Mickaël Salaün

On 22/02/2017 02:26, Mickaël Salaün wrote:
> Add a basic sandbox tool to create a process isolated from some part of
> the system. This sandbox create a read-only environment. It is only
> allowed to write to a character device such as a TTY:
> 
>   # :> X
>   # echo $?
>   0
>   # ./samples/bpf/landlock1 /bin/sh -i
>   Launching a new sandboxed process.
>   # :> Y
>   cannot create Y: Operation not permitted
> 
> Changes since v4:
> * write Landlock rule in C and compiled it with LLVM
> * remove cgroup handling
> * remove path handling: only handle a read-only environment
> * remove errno return codes
> 
> Changes since v3:
> * remove seccomp and origin field: completely free from seccomp programs
> * handle more FS-related hooks
> * handle inode hooks and directory traversal
> * add faked but consistent view thanks to ENOENT
> * add /lib64 in the example
> * fix spelling
> * rename some types and definitions (e.g. SECCOMP_ADD_LANDLOCK_RULE)
> 
> Changes since v2:
> * use BPF_PROG_ATTACH for cgroup handling
> 
> Signed-off-by: Mickaël Salaün <m...@digikod.net>
> Cc: Alexei Starovoitov <a...@kernel.org>
> Cc: Andy Lutomirski <l...@amacapital.net>
> Cc: Daniel Borkmann <dan...@iogearbox.net>
> Cc: David S. Miller <da...@davemloft.net>
> Cc: James Morris <james.l.mor...@oracle.com>
> Cc: Kees Cook <keesc...@chromium.org>
> Cc: Serge E. Hallyn <se...@hallyn.com>
> ---
>  samples/bpf/.gitignore   |  32 ++
>  samples/bpf/Makefile |   4 ++
>  samples/bpf/bpf_load.c   |  26 +--
>  samples/bpf/landlock1_kern.c |  46 +++
>  samples/bpf/landlock1_user.c | 102 
> +++
>  5 files changed, 206 insertions(+), 4 deletions(-)
>  create mode 100644 samples/bpf/.gitignore
>  create mode 100644 samples/bpf/landlock1_kern.c
>  create mode 100644 samples/bpf/landlock1_user.c
> 
> diff --git a/samples/bpf/.gitignore b/samples/bpf/.gitignore
> new file mode 100644
> index ..a7562a5ef4c2
> --- /dev/null
> +++ b/samples/bpf/.gitignore
> @@ -0,0 +1,32 @@
> +fds_example
> +lathist
> +lwt_len_hist
> +map_perf_test
> +offwaketime
> +sampleip
> +sockex1
> +sockex2
> +sockex3
> +sock_example
> +spintest
> +tc_l2_redirect
> +test_cgrp2_array_pin
> +test_cgrp2_attach
> +test_cgrp2_attach2
> +test_cgrp2_sock
> +test_cgrp2_sock2
> +test_current_task_under_cgroup
> +test_lru_dist
> +test_overhead
> +test_probe_write_user
> +trace_event
> +trace_output
> +tracex1
> +tracex2
> +tracex3
> +tracex4
> +tracex5
> +tracex6
> +xdp1
> +xdp2
> +xdp_tx_iptunnel

Please ignore this hunk, it was part of another patch series…



signature.asc
Description: OpenPGP digital signature


Re: [PATCH v5 10/10] landlock: Add user and kernel documentation for Landlock

2017-02-21 Thread Mickaël Salaün

On 22/02/2017 06:21, Andy Lutomirski wrote:
> On Tue, Feb 21, 2017 at 5:26 PM, Mickaël Salaün <m...@digikod.net> wrote:
>> This documentation can be built with the Sphinx framework.
>>
>> Signed-off-by: Mickaël Salaün <m...@digikod.net>
>> Cc: Alexei Starovoitov <a...@kernel.org>
>> Cc: Andy Lutomirski <l...@amacapital.net>
>> Cc: Daniel Borkmann <dan...@iogearbox.net>
>> Cc: David S. Miller <da...@davemloft.net>
>> Cc: James Morris <james.l.mor...@oracle.com>
>> Cc: Jonathan Corbet <cor...@lwn.net>
>> Cc: Kees Cook <keesc...@chromium.org>
>> Cc: Serge E. Hallyn <se...@hallyn.com>
> 
> 
>> +
>> +Writing a rule
>> +--
>> +
>> +To enforce a security policy, a thread first needs to create a Landlock 
>> rule.
>> +The easiest way to write an eBPF program depicting a security rule is to 
>> write
>> +it in the C language.  As described in *samples/bpf/README.rst*, LLVM can
>> +compile such programs.  Files *samples/bpf/landlock1_kern.c* and those in
>> +*tools/testing/selftests/landlock/rules/* can be used as examples.  The
>> +following example is a simple rule to forbid file creation, whatever syscall
>> +may be used (e.g. open, mkdir, link...).
>> +
>> +.. code-block:: c
>> +
>> +static int deny_file_creation(struct landlock_context *ctx)
>> +{
>> +if (ctx->arg2 & LANDLOCK_ACTION_FS_NEW)
>> +return 1;
>> +return 0;
>> +}
>> +
> 
> Would it make sense to define landlock_context (or at least a prefix
> thereof) in here?  Also, can't "arg2" have a better name?

arg2 is a generic name. Its meaning depends on the Landlock event, here
it is an action bitfield (FS event).

> 
> Can you specify what the return value means?  Are 0 and 1 the only
> choices?  Would "KILL" be useful?  How about "COREDUMP"?

This is explained thereafter and in the kernel Q section. I need to
briefly introduce that here.

> 
>> +File system action types
>> +
>> +
>> +Flags are used to express actions.  This makes it possible to compose 
>> actions
>> +and leaves room for future improvements to add more fine-grained action 
>> types.
>> +
>> +.. kernel-doc:: include/uapi/linux/bpf.h
>> +:doc: landlock_action_fs
>> +
>> +.. flat-table:: FS action types availability
>> +
>> +* - flags
>> +  - since
>> +
>> +* - LANDLOCK_ACTION_FS_EXEC
>> +  - v1
>> +
>> +* - LANDLOCK_ACTION_FS_WRITE
>> +  - v1
>> +
>> +* - LANDLOCK_ACTION_FS_READ
>> +  - v1
>> +
>> +* - LANDLOCK_ACTION_FS_NEW
>> +  - v1
>> +
>> +* - LANDLOCK_ACTION_FS_GET
>> +  - v1
>> +
>> +* - LANDLOCK_ACTION_FS_REMOVE
>> +  - v1
>> +
>> +* - LANDLOCK_ACTION_FS_IOCTL
>> +  - v1
>> +
>> +* - LANDLOCK_ACTION_FS_LOCK
>> +  - v1
>> +
>> +* - LANDLOCK_ACTION_FS_FCNTL
>> +  - v1
> 
> What happens if you run an old program on a new kernel?  Can you get
> unexpected action types?

The old flags will still make sense, the new ones should be ignored by
the rule.

> 
>> +
>> +
>> +Ability types
>> +-
>> +
>> +The ability of a Landlock rule describes the available features (i.e. 
>> context
>> +fields and helpers).  This is useful to abstract user-space privileges for
>> +Landlock rules, which may not need all abilities (e.g. debug).  Only the
>> +minimal set of abilities should be used (e.g. disable debug once in
>> +production).
>> +
>> +
>> +.. kernel-doc:: include/uapi/linux/bpf.h
>> +:doc: landlock_subtype_ability
>> +
>> +.. flat-table:: Ability types availability
>> +
>> +* - flags
>> +  - since
>> +  - capability
>> +
>> +* - LANDLOCK_SUBTYPE_ABILITY_WRITE
>> +  - v1
>> +  - CAP_SYS_ADMIN
>> +
>> +* - LANDLOCK_SUBTYPE_ABILITY_DEBUG
>> +  - v1
>> +  - CAP_SYS_ADMIN
>> +
> 
> What do "WRITE" and "DEBUG" mean in this context?  I'm totally lost.
> 
> Hmm.  Reading below, "WRITE" seems to mean "modify state".  Would that
> be accurate?

That is correct, but handling a state in a safe way imply more than only
the ability to "write" outside bpfland (e.g. sequential execution).

> 
>> +
>> +Helper functions
>> +
>> +
>> +See *include/uapi/linux/bpf.h* for functions documentation.
>> +
>> +.. flat-table:: Generic functions availability
>> +
> 
>> +
>> +* - bpf_get_current_comm
>> +  - v1
>> +  - LANDLOCK_SUBTYPE_ABILITY_DEBUG
> 
> What would this be used for?

To get more information about the process which trigger an action?

> 
>> +* - bpf_get_trace_printk
>> +  - v1
>> +  - LANDLOCK_SUBTYPE_ABILITY_DEBUG
>> +
> 
> This is different from the other DEBUG stuff in that it has side
> effects.  I wonder if it should have a different flag.

I think the debug flag is a clear warning to not ship a rule using this
ability. Maybe a sub-flag LANDLOCK_SUBTYPE_ABILITY_DEBUG_PRINT would fit
here?

 Mickaël



signature.asc
Description: OpenPGP digital signature


[PATCH v5 00/10] Landlock LSM: Toward unprivileged sandboxing

2017-02-21 Thread Mickaël Salaün
ause only checking in LSM hooks
  * architecture agnostic
* switch from cBPF to eBPF:
  * new eBPF program types dedicated to Landlock
  * custom functions used by the eBPF program
  * gain some new features (e.g. 10 registers, can load values of different
size, LLVM translator) but only a few functions allowed and a dedicated 
map
type
  * new context: LSM hook ID, cookie and LSM hook arguments
  * need to set the sysctl kernel.unprivileged_bpf_disable to 0 (default value)
to be able to load hook filters as unprivileged users
* smaller and simpler:
  * no more checker groups but dedicated arraymap of handles
  * simpler userland structs thanks to eBPF functions
* distinctive name: Landlock


[1] https://lkml.kernel.org/r/20161026065654.19166-1-...@digikod.net
[2] https://lkml.kernel.org/r/5828776a.1010...@digikod.net
[3] 
https://lkml.kernel.org/r/1477390454-12553-1-git-send-email-dan...@zonque.org
[4] 
https://lkml.kernel.org/r/20160829114542.GA20836@ircssh.c.rugged-nimbus-611.internal
[5] https://lkml.kernel.org/r/20161221231506.19800-1-...@digikod.net

Regards,

Mickaël Salaün (10):
  bpf: Add eBPF program subtype and is_valid_subtype() verifier
  bpf,landlock: Define an eBPF program type for Landlock
  bpf: Define handle_fs and add a new helper bpf_handle_fs_get_mode()
  landlock: Add LSM hooks related to filesystem
  seccomp: Split put_seccomp_filter() with put_seccomp()
  seccomp,landlock: Handle Landlock events per process hierarchy
  bpf: Add a Landlock sandbox example
  seccomp: Enhance test_harness with an assert step mechanism
  bpf,landlock: Add tests for Landlock
  landlock: Add user and kernel documentation for Landlock

 Documentation/security/index.rst   |   1 +
 Documentation/security/landlock/index.rst  |  19 +
 Documentation/security/landlock/kernel.rst | 132 +++
 Documentation/security/landlock/user.rst   | 298 +++
 include/linux/bpf.h|  40 +-
 include/linux/filter.h |   1 +
 include/linux/landlock.h   |  80 ++
 include/linux/lsm_hooks.h  |   5 +
 include/linux/seccomp.h|  12 +-
 include/uapi/linux/bpf.h   | 125 ++-
 include/uapi/linux/seccomp.h   |   1 +
 kernel/bpf/Makefile|   2 +-
 kernel/bpf/helpers_fs.c|  52 ++
 kernel/bpf/syscall.c   |   5 +-
 kernel/bpf/verifier.c  |  16 +-
 kernel/fork.c  |  16 +-
 kernel/seccomp.c   |  26 +-
 kernel/trace/bpf_trace.c   |  15 +-
 net/core/filter.c  |  48 +-
 samples/bpf/.gitignore |  32 +
 samples/bpf/Makefile   |   4 +
 samples/bpf/bpf_helpers.h  |   2 +
 samples/bpf/bpf_load.c |  29 +-
 samples/bpf/fds_example.c  |   2 +-
 samples/bpf/landlock1_kern.c   |  46 +
 samples/bpf/landlock1_user.c   | 102 +++
 samples/bpf/sock_example.c |   2 +-
 samples/bpf/test_cgrp2_attach.c|   2 +-
 samples/bpf/test_cgrp2_attach2.c   |   2 +-
 samples/bpf/test_cgrp2_sock.c  |   2 +-
 security/Kconfig   |   1 +
 security/Makefile  |   2 +
 security/landlock/Kconfig  |  18 +
 security/landlock/Makefile |   5 +
 security/landlock/common.h |  25 +
 security/landlock/hooks.c  | 962 +
 security/landlock/manager.c| 321 +++
 security/security.c|   7 +-
 tools/include/uapi/linux/bpf.h | 125 ++-
 tools/lib/bpf/bpf.c|   5 +-
 tools/lib/bpf/bpf.h|   2 +-
 tools/lib/bpf/libbpf.c |   4 +-
 tools/perf/tests/bpf.c |   2 +-
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/bpf/test_tag.c |   2 +-
 tools/testing/selftests/bpf/test_verifier.c|  57 +-
 tools/testing/selftests/landlock/.gitignore|   2 +
 tools/testing/selftests/landlock/Makefile  |  47 +
 tools/testing/selftests/landlock/rules/Makefile|  52 ++
 tools/testing/selftests/landlock/rules/README.rst  |   1 +
 .../testing/selftests/landlock/rules/bpf_helpers.h |   1 +
 tools/testing/selftests/landlock/rules/fs1.c   |  31 +
 tools/testing/selftests/landlock/rules/fs2.c   |  31 +
 tools/testing/selftests/landlock/test_fs.c | 347 
 tools/t

[PATCH v5 02/10] bpf,landlock: Define an eBPF program type for Landlock

2017-02-21 Thread Mickaël Salaün
Add a new type of eBPF program used by Landlock rules.

This new BPF program type will be registered with the Landlock LSM
initialization.

Add an initial Landlock Kconfig.

Changes since v4:
* merge a minimal (not enabled) LSM code and Kconfig in this commit

Changes since v3:
* split commit
* revamp the landlock_context:
  * add arch, syscall_nr and syscall_cmd (ioctl, fcntl…) to be able to
cross-check action with the event type
  * replace args array with dedicated fields to ease the addition of new
fields

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---
 include/linux/landlock.h   |  80 ++
 include/uapi/linux/bpf.h   | 105 ++
 security/Kconfig   |   1 +
 security/Makefile  |   2 +
 security/landlock/Kconfig  |  18 ++
 security/landlock/Makefile |   3 +
 security/landlock/common.h |  25 +
 security/landlock/hooks.c  | 124 +
 tools/include/uapi/linux/bpf.h | 105 ++
 9 files changed, 463 insertions(+)
 create mode 100644 include/linux/landlock.h
 create mode 100644 security/landlock/Kconfig
 create mode 100644 security/landlock/Makefile
 create mode 100644 security/landlock/common.h
 create mode 100644 security/landlock/hooks.c

diff --git a/include/linux/landlock.h b/include/linux/landlock.h
new file mode 100644
index ..6be3c02dfc7c
--- /dev/null
+++ b/include/linux/landlock.h
@@ -0,0 +1,80 @@
+/*
+ * Landlock LSM - Public headers
+ *
+ * Copyright © 2017 Mickaël Salaün <m...@digikod.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _LINUX_LANDLOCK_H
+#define _LINUX_LANDLOCK_H
+#ifdef CONFIG_SECURITY_LANDLOCK
+
+#include  /* _LANDLOCK_SUBTYPE_EVENT_LAST */
+#include  /* atomic_t */
+
+/*
+ * This is not intended for the UAPI headers. Each userland software should use
+ * a static minimal version for the required features as explained in the
+ * documentation.
+ */
+#define LANDLOCK_VERSION 1
+
+struct landlock_rule {
+   atomic_t usage;
+   struct landlock_rule *prev;
+   struct bpf_prog *prog;
+};
+
+/**
+ * struct landlock_node - node in the rule hierarchy
+ *
+ * This is created when a task inserts its first rule in the Landlock rule
+ * hierarchy. The set of Landlock rules referenced by this node is then
+ * enforced for all the tasks that inherit this node. However, if a task is
+ * cloned before inserting any rule, it doesn't get a dedicated node and its
+ * children will not inherit any rules from this task.
+ *
+ * @usage: reference count to manage the node lifetime
+ * @rule: list of Landlock rules managed by this node
+ * @prev: reference the parent node
+ * @owner: reference the address of the node in the  landlock_events.
+ * This is needed to know if we need to append a rule to the current
+ * node or create a new node.
+ */
+struct landlock_node {
+   atomic_t usage;
+   struct landlock_rule *rule;
+   struct landlock_node *prev;
+   struct landlock_node **owner;
+};
+
+/**
+ * struct landlock_events - Landlock event rules enforced on a thread
+ *
+ * This is used for low performance impact when forking a process. Instead of
+ * copying the full array and incrementing the usage of each entries, only
+ * create a pointer to  landlock_events and increments its usage.
+ *
+ * @usage: reference count to manage the object lifetime. When a thread need to
+ * add Landlock rules and if @usage is greater than 1, then the thread
+ * must duplicate  landlock_events to not change the children's
+ * rules as well.
+ * @nodes: array of non-NULL  landlock_node pointers
+ */
+struct landlock_events {
+   atomic_t usage;
+   struct landlock_node *nodes[_LANDLOCK_SUBTYPE_EVENT_LAST];
+};
+
+void put_landlock_events(struct landlock_events *events);
+
+#ifdef CONFIG_SECCOMP_FILTER
+int landlock_seccomp_append_prog(unsigned int flags,
+   const char __user *user_bpf_fd);
+#endif /* CONFIG_SECCOMP_FILTER */
+
+#endif /* CONFIG_SECURITY_LANDLOCK */
+#endif /* _LINUX_LANDLOCK_H */
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 240c76f09d0d..c9c909a84f0b 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -112,6 +112,7 @@ enum bpf_prog_type {
BPF_PROG_TYPE_LWT_IN,
BPF_PROG_TYPE_LWT_OUT,
BPF_PROG_TYPE_LWT_XMIT,
+   BPF_PROG_TYPE_LANDLOCK,
 };

[PATCH v5 08/10] seccomp: Enhance test_harness with an assert step mechanism

2017-02-21 Thread Mickaël Salaün
This is useful to return an information about the error without being
able to write to TH_LOG_STREAM.

Helpers from test_harness.h may be useful outside of the seccomp
directory.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Shuah Khan <sh...@kernel.org>
Cc: Will Drewry <w...@chromium.org>
---
 tools/testing/selftests/seccomp/test_harness.h | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/seccomp/test_harness.h 
b/tools/testing/selftests/seccomp/test_harness.h
index a786c69c7584..77e407663e06 100644
--- a/tools/testing/selftests/seccomp/test_harness.h
+++ b/tools/testing/selftests/seccomp/test_harness.h
@@ -397,7 +397,7 @@ struct __test_metadata {
const char *name;
void (*fn)(struct __test_metadata *);
int termsig;
-   int passed;
+   __s8 passed;
int trigger; /* extra handler after the evaluation */
struct __test_metadata *prev, *next;
 };
@@ -476,6 +476,12 @@ void __run_test(struct __test_metadata *t)
"instead of by signal (code: %d)\n",
t->name,
WEXITSTATUS(status));
+   } else if (t->passed < 0) {
+   fprintf(TH_LOG_STREAM,
+   "%s: Failed at step #%d\n",
+   t->name,
+   t->passed * -1);
+   t->passed = 0;
}
} else if (WIFSIGNALED(status)) {
t->passed = 0;
-- 
2.11.0



[PATCH v5 01/10] bpf: Add eBPF program subtype and is_valid_subtype() verifier

2017-02-21 Thread Mickaël Salaün
The goal of the program subtype is to be able to have different static
fine-grained verifications for a unique program type.

The struct bpf_verifier_ops gets a new optional function:
is_valid_subtype(). This new verifier is called at the beginning of the
eBPF program verification to check if the (optional) program subtype is
valid.

For now, only Landlock eBPF programs are using a program subtype (see
next commit) but this could be used by other program types in the future.

Changes since v4:
* replace the "status" field with "version" (more generic)
* replace the "access" field with "ability" (less confusing)

Changes since v3:
* remove the "origin" field
* add an "option" field
* cleanup comments

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Link: https://lkml.kernel.org/r/20160827205559.ga43...@ast-mbp.thefacebook.com
---
 include/linux/bpf.h |  7 +++--
 include/linux/filter.h  |  1 +
 include/uapi/linux/bpf.h| 10 ++
 kernel/bpf/syscall.c|  5 +--
 kernel/bpf/verifier.c   | 10 --
 kernel/trace/bpf_trace.c| 15 ++---
 net/core/filter.c   | 48 ++---
 samples/bpf/bpf_load.c  |  3 +-
 samples/bpf/fds_example.c   |  2 +-
 samples/bpf/sock_example.c  |  2 +-
 samples/bpf/test_cgrp2_attach.c |  2 +-
 samples/bpf/test_cgrp2_attach2.c|  2 +-
 samples/bpf/test_cgrp2_sock.c   |  2 +-
 tools/include/uapi/linux/bpf.h  | 10 ++
 tools/lib/bpf/bpf.c |  5 ++-
 tools/lib/bpf/bpf.h |  2 +-
 tools/lib/bpf/libbpf.c  |  4 +--
 tools/perf/tests/bpf.c  |  2 +-
 tools/testing/selftests/bpf/test_tag.c  |  2 +-
 tools/testing/selftests/bpf/test_verifier.c |  3 +-
 20 files changed, 95 insertions(+), 42 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 909fc033173a..dd954048aa19 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -154,19 +154,22 @@ struct bpf_prog;
 
 struct bpf_verifier_ops {
/* return eBPF function prototype for verification */
-   const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id 
func_id);
+   const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id func_id,
+ union bpf_prog_subtype *prog_subtype);
 
/* return true if 'size' wide access at offset 'off' within bpf_context
 * with 'type' (read or write) is allowed
 */
bool (*is_valid_access)(int off, int size, enum bpf_access_type type,
-   enum bpf_reg_type *reg_type);
+   enum bpf_reg_type *reg_type,
+   union bpf_prog_subtype *prog_subtype);
int (*gen_prologue)(struct bpf_insn *insn, bool direct_write,
const struct bpf_prog *prog);
u32 (*convert_ctx_access)(enum bpf_access_type type,
  const struct bpf_insn *src,
  struct bpf_insn *dst,
  struct bpf_prog *prog);
+   bool (*is_valid_subtype)(union bpf_prog_subtype *prog_subtype);
 };
 
 struct bpf_prog_type_list {
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 0c167fdee5f7..1f49b19a87c1 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -417,6 +417,7 @@ struct bpf_prog {
enum bpf_prog_type  type;   /* Type of BPF program */
u32 len;/* Number of filter blocks */
u8  tag[BPF_TAG_SIZE];
+   union bpf_prog_subtype  subtype;/* For fine-grained 
verifications */
struct bpf_prog_aux *aux;   /* Auxiliary fields */
struct sock_fprog_kern  *orig_prog; /* Original BPF program */
unsigned int(*bpf_func)(const void *ctx,
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 0539a0ceef38..240c76f09d0d 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -145,6 +145,15 @@ enum bpf_attach_type {
  */
 #define BPF_F_NO_COMMON_LRU(1U << 1)
 
+union bpf_prog_subtype {
+   struct {
+   __u32   version; /* cf. documentation */
+   __u32   event; /* enum landlock_subtype_event */
+   __aligned_u64   ability; /* LANDLOCK_SUBTYPE_ABILITY_* */
+   __aligned_u64   option; /* LANDLOCK_SUBTYPE_OPTION_* */
+   } landlock_rul

[PATCH v5 07/10] bpf: Add a Landlock sandbox example

2017-02-21 Thread Mickaël Salaün
Add a basic sandbox tool to create a process isolated from some part of
the system. This sandbox create a read-only environment. It is only
allowed to write to a character device such as a TTY:

  # :> X
  # echo $?
  0
  # ./samples/bpf/landlock1 /bin/sh -i
  Launching a new sandboxed process.
  # :> Y
  cannot create Y: Operation not permitted

Changes since v4:
* write Landlock rule in C and compiled it with LLVM
* remove cgroup handling
* remove path handling: only handle a read-only environment
* remove errno return codes

Changes since v3:
* remove seccomp and origin field: completely free from seccomp programs
* handle more FS-related hooks
* handle inode hooks and directory traversal
* add faked but consistent view thanks to ENOENT
* add /lib64 in the example
* fix spelling
* rename some types and definitions (e.g. SECCOMP_ADD_LANDLOCK_RULE)

Changes since v2:
* use BPF_PROG_ATTACH for cgroup handling

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---
 samples/bpf/.gitignore   |  32 ++
 samples/bpf/Makefile |   4 ++
 samples/bpf/bpf_load.c   |  26 +--
 samples/bpf/landlock1_kern.c |  46 +++
 samples/bpf/landlock1_user.c | 102 +++
 5 files changed, 206 insertions(+), 4 deletions(-)
 create mode 100644 samples/bpf/.gitignore
 create mode 100644 samples/bpf/landlock1_kern.c
 create mode 100644 samples/bpf/landlock1_user.c

diff --git a/samples/bpf/.gitignore b/samples/bpf/.gitignore
new file mode 100644
index ..a7562a5ef4c2
--- /dev/null
+++ b/samples/bpf/.gitignore
@@ -0,0 +1,32 @@
+fds_example
+lathist
+lwt_len_hist
+map_perf_test
+offwaketime
+sampleip
+sockex1
+sockex2
+sockex3
+sock_example
+spintest
+tc_l2_redirect
+test_cgrp2_array_pin
+test_cgrp2_attach
+test_cgrp2_attach2
+test_cgrp2_sock
+test_cgrp2_sock2
+test_current_task_under_cgroup
+test_lru_dist
+test_overhead
+test_probe_write_user
+trace_event
+trace_output
+tracex1
+tracex2
+tracex3
+tracex4
+tracex5
+tracex6
+xdp1
+xdp2
+xdp_tx_iptunnel
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 09e9d535bd74..3d3afd709635 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -34,6 +34,7 @@ hostprogs-y += sampleip
 hostprogs-y += tc_l2_redirect
 hostprogs-y += lwt_len_hist
 hostprogs-y += xdp_tx_iptunnel
+hostprogs-y += landlock1
 
 # Libbpf dependencies
 LIBBPF := ../../tools/lib/bpf/bpf.o
@@ -72,6 +73,7 @@ sampleip-objs := bpf_load.o $(LIBBPF) sampleip_user.o
 tc_l2_redirect-objs := bpf_load.o $(LIBBPF) tc_l2_redirect_user.o
 lwt_len_hist-objs := bpf_load.o $(LIBBPF) lwt_len_hist_user.o
 xdp_tx_iptunnel-objs := bpf_load.o $(LIBBPF) xdp_tx_iptunnel_user.o
+landlock1-objs := bpf_load.o $(LIBBPF) landlock1_user.o
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
@@ -105,6 +107,7 @@ always += trace_event_kern.o
 always += sampleip_kern.o
 always += lwt_len_hist_kern.o
 always += xdp_tx_iptunnel_kern.o
+always += landlock1_kern.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 HOSTCFLAGS += -I$(srctree)/tools/lib/
@@ -139,6 +142,7 @@ HOSTLOADLIBES_sampleip += -lelf
 HOSTLOADLIBES_tc_l2_redirect += -l elf
 HOSTLOADLIBES_lwt_len_hist += -l elf
 HOSTLOADLIBES_xdp_tx_iptunnel += -lelf
+HOSTLOADLIBES_landlock1 += -lelf
 
 # Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on 
cmdline:
 #  make samples/bpf/ LLC=~/git/llvm/build/bin/llc 
CLANG=~/git/llvm/build/bin/clang
diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index d23dc13ab0f2..78df39cf8b2f 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -68,6 +68,7 @@ static int load_and_attach(const char *event, struct bpf_insn 
*prog, int size)
bool is_perf_event = strncmp(event, "perf_event", 10) == 0;
bool is_cgroup_skb = strncmp(event, "cgroup/skb", 10) == 0;
bool is_cgroup_sk = strncmp(event, "cgroup/sock", 11) == 0;
+   bool is_landlock = strncmp(event, "landlock", 8) == 0;
size_t insns_cnt = size / sizeof(struct bpf_insn);
enum bpf_prog_type prog_type;
char buf[256];
@@ -93,6 +94,12 @@ static int load_and_attach(const char *event, struct 
bpf_insn *prog, int size)
prog_type = BPF_PROG_TYPE_CGROUP_SKB;
} else if (is_cgroup_sk) {
prog_type = BPF_PROG_TYPE_CGROUP_SOCK;
+   } else if (is_landlock) {
+   prog_type = BPF_PROG_TYPE_LANDLOCK;
+   if (!subtype.landlock_rule.event) {
+   printf("No subtype\n");
+   return -1;
+   }
} else {

[PATCH v5 09/10] bpf,landlock: Add tests for Landlock

2017-02-21 Thread Mickaël Salaün
Test basic context access and filesystem event with multiple cases.

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
Cc: Shuah Khan <sh...@kernel.org>
Cc: Will Drewry <w...@chromium.org>
---
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/bpf/test_verifier.c|  54 +++-
 tools/testing/selftests/landlock/.gitignore|   2 +
 tools/testing/selftests/landlock/Makefile  |  47 +++
 tools/testing/selftests/landlock/rules/Makefile|  52 +++
 tools/testing/selftests/landlock/rules/README.rst  |   1 +
 .../testing/selftests/landlock/rules/bpf_helpers.h |   1 +
 tools/testing/selftests/landlock/rules/fs1.c   |  31 ++
 tools/testing/selftests/landlock/rules/fs2.c   |  31 ++
 tools/testing/selftests/landlock/test_fs.c | 347 +
 10 files changed, 566 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/landlock/.gitignore
 create mode 100644 tools/testing/selftests/landlock/Makefile
 create mode 100644 tools/testing/selftests/landlock/rules/Makefile
 create mode 12 tools/testing/selftests/landlock/rules/README.rst
 create mode 12 tools/testing/selftests/landlock/rules/bpf_helpers.h
 create mode 100644 tools/testing/selftests/landlock/rules/fs1.c
 create mode 100644 tools/testing/selftests/landlock/rules/fs2.c
 create mode 100644 tools/testing/selftests/landlock/test_fs.c

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 831022b12848..a8dadcfa4c01 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -10,6 +10,7 @@ TARGETS += futex
 TARGETS += gpio
 TARGETS += ipc
 TARGETS += kcmp
+TARGETS += landlock
 TARGETS += lib
 TARGETS += membarrier
 TARGETS += memfd
diff --git a/tools/testing/selftests/bpf/test_verifier.c 
b/tools/testing/selftests/bpf/test_verifier.c
index 15eeb79104fe..ee1d439e48e4 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -4451,7 +4451,59 @@ static struct bpf_test tests[] = {
.errstr = "R0 min value is negative, either use unsigned index 
or do a if (index >=0) check.",
.result = REJECT,
.result_unpriv = REJECT,
-   }
+   },
+   {
+   "landlock/fs: always accept",
+   .insns = {
+   BPF_MOV32_IMM(BPF_REG_0, 0),
+   BPF_EXIT_INSN(),
+   },
+   .result = ACCEPT,
+   .prog_type = BPF_PROG_TYPE_LANDLOCK,
+   .prog_subtype = {
+   .landlock_rule = {
+   .version = 1,
+   .event = LANDLOCK_SUBTYPE_EVENT_FS,
+   }
+   },
+   },
+   {
+   "landlock/fs: read context",
+   .insns = {
+   BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
+   BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, status)),
+   /* test operations on raw values */
+   BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1),
+   BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, arch)),
+   BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1),
+   BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, syscall_nr)),
+   BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1),
+   BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, syscall_cmd)),
+   BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1),
+   BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, event)),
+   BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1),
+   BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, arg1)),
+   BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_6,
+   offsetof(struct landlock_context, arg2)),
+   BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1),
+   BPF_MOV32_IMM(BPF_REG_0, 0),
+   BPF_EXIT_INSN(),
+   },
+   .result = ACCEPT,
+   .prog_type = BPF_PROG_TYPE_LANDLOCK,
+   .prog_subtyp

[PATCH v5 04/10] landlock: Add LSM hooks related to filesystem

2017-02-21 Thread Mickaël Salaün
Handle 33 filesystem-related LSM hooks for the Landlock filesystem
event: LANDLOCK_SUBTYPE_EVENT_FS.

A Landlock event wrap LSM hooks for similar kernel object types (e.g.
struct file, struct path...). Multiple LSM hooks can trigger the same
Landlock event.

Landlock handle nine coarse-grained actions: read, write, execute, new,
get, remove, ioctl, lock and fcntl. Each of them abstract LSM hook
access control in a way that can be extended in the future.

The Landlock LSM hook registration is done after other LSM to only run
actions from user-space, via eBPF programs, if the access was granted by
major (privileged) LSMs.

Changes since v4:
* add LSM hook abstraction called Landlock event
  * use the compiler type checking to verify hooks use by an event
  * handle all filesystem related LSM hooks (e.g. file_permission,
mmap_file, sb_mount...)
* register BPF programs for Landlock just after LSM hooks registration
* move hooks registration after other LSMs
* add failsafes to check if a hook is not used by the kernel
* allow partial raw value access form the context (needed for programs
  generated by LLVM)

Changes since v3:
* split commit
* add hooks dealing with struct inode and struct path pointers:
  inode_permission and inode_getattr
* add abstraction over eBPF helper arguments thanks to wrapping structs

Signed-off-by: Mickaël Salaün <m...@digikod.net>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Daniel Borkmann <dan...@iogearbox.net>
Cc: David S. Miller <da...@davemloft.net>
Cc: James Morris <james.l.mor...@oracle.com>
Cc: Kees Cook <keesc...@chromium.org>
Cc: Serge E. Hallyn <se...@hallyn.com>
---
 include/linux/lsm_hooks.h  |   5 +
 security/landlock/Makefile |   2 +
 security/landlock/hooks.c  | 794 -
 security/security.c|   7 +-
 4 files changed, 806 insertions(+), 2 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 558adfa5c8a8..069af34301d4 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1933,5 +1933,10 @@ void __init loadpin_add_hooks(void);
 #else
 static inline void loadpin_add_hooks(void) { };
 #endif
+#ifdef CONFIG_SECURITY_LANDLOCK
+extern void __init landlock_add_hooks(void);
+#else
+static inline void __init landlock_add_hooks(void) { }
+#endif /* CONFIG_SECURITY_LANDLOCK */
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/security/landlock/Makefile b/security/landlock/Makefile
index b91af42f0c32..8dc8bde660bd 100644
--- a/security/landlock/Makefile
+++ b/security/landlock/Makefile
@@ -1,3 +1,5 @@
+ccflags-$(CONFIG_SECURITY_LANDLOCK) += -Werror=unused-function
+
 obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o
 
 landlock-y := hooks.o
diff --git a/security/landlock/hooks.c b/security/landlock/hooks.c
index 6c1ad0e03cfc..88ebe3f01758 100644
--- a/security/landlock/hooks.c
+++ b/security/landlock/hooks.c
@@ -21,14 +21,797 @@
 #include  /* offsetof */
 #include  /* uintptr_t */
 
+/* permissions translation */
+#include  /* MAY_* */
+#include  /* PROT_* */
+
+/* hook arguments */
+#include 
+#include  /* struct dentry */
+#include  /* struct inode, struct iattr */
+#include  /* struct vm_area_struct */
+#include  /* struct vfsmount */
+#include  /* struct path */
+#include  /* struct task_struct */
+#include  /* struct timespec */
+
+
+#include "common.h" /* get_index() */
+
 #define CTX_ARG_NB 2
 
+/* separators */
+#define SEP_COMMA() ,
+#define SEP_SPACE()
+#define SEP_AND() &&
+
+#define MAP2x1(s, m, x1, x2, ...) m(x1, x2)
+#define MAP2x2(s, m, x1, x2, ...) m(x1, x2) s() MAP2x1(s, m, __VA_ARGS__)
+#define MAP2x3(s, m, x1, x2, ...) m(x1, x2) s() MAP2x2(s, m, __VA_ARGS__)
+#define MAP2x4(s, m, x1, x2, ...) m(x1, x2) s() MAP2x3(s, m, __VA_ARGS__)
+#define MAP2x5(s, m, x1, x2, ...) m(x1, x2) s() MAP2x4(s, m, __VA_ARGS__)
+#define MAP2x6(s, m, x1, x2, ...) m(x1, x2) s() MAP2x5(s, m, __VA_ARGS__)
+#define MAP2x(n, ...) MAP2x##n(__VA_ARGS__)
+
+#define MAP1x1(s, m, x1, ...) m(x1)
+#define MAP1x2(s, m, x1, ...) m(x1) s() MAP1x1(s, m, __VA_ARGS__)
+#define MAP1x(n, ...) MAP1x##n(__VA_ARGS__)
+
+#define SKIP2x1(x1, x2, ...) __VA_ARGS__
+#define SKIP2x2(x1, x2, ...) SKIP2x1(__VA_ARGS__)
+#define SKIP2x3(x1, x2, ...) SKIP2x2(__VA_ARGS__)
+#define SKIP2x4(x1, x2, ...) SKIP2x3(__VA_ARGS__)
+#define SKIP2x5(x1, x2, ...) SKIP2x4(__VA_ARGS__)
+#define SKIP2x6(x1, x2, ...) SKIP2x5(__VA_ARGS__)
+#define SKIP2x(n, ...) SKIP2x##n(__VA_ARGS__)
+
+/* LSM hook argument helpers */
+#define MAP_HOOK_COMMA(n, ...) MAP2x(n, SEP_COMMA, __VA_ARGS__)
+
+#define GET_HOOK_TA(t, a) t a
+
+/* Landlock event argument helpers  */
+#define MAP_EVENT_COMMA(h, n, m, ...) MAP2x(n, SEP_COMMA, m, SKIP2x(h, 
__VA_ARGS__))
+#define MAP_EVENT_SPACE(h, n, m, ...) MAP2x(n, SEP_SPACE, m, SKIP2x(h, 
__VA_ARGS__))
+#define MAP_EVENT_AND(h, n, m, ...) MAP2x(n, SEP_AND, m, SKIP2x(h, 
__VA_ARGS__))
+
+#defi

  1   2   3   >