Re: [PATCH v30 02/12] landlock: Add ruleset and domain management

2021-03-25 Thread Mickaël Salaün


On 24/03/2021 21:31, James Morris wrote:
> On Fri, 19 Mar 2021, Mickaël Salaün wrote:
> 
>>
 Cc: Kees Cook 
 Signed-off-by: Mickaël Salaün 
 Acked-by: Serge Hallyn 
 Link: https://lore.kernel.org/r/20210316204252.427806-3-...@digikod.net
>>>
>>> (Aside: you appear to be self-adding your Link: tags -- AIUI, this is
>>> normally done by whoever pulls your series. I've only seen Link: tags
>>> added when needing to refer to something else not included in the
>>> series.)
>>
>> It is an insurance to not lose history. :)
> 
> How will history be lost? The code is in the repo and discussions can 
> easily be found by searching for subjects or message IDs.

The (full and ordered) history may be hard to find without any
Message-ID in commit messages. The Lore links keep that information (in
the commit message) and redirect to the related archived email thread,
which is very handy. For instance, Linus can rely on those links to
judge the quality of a patch:
https://lore.kernel.org/lkml/CAHk-=wh7xY3UF7zEc0BNVNjOox59jYBW-Gfi7=emm+bxpwc...@mail.gmail.com/

> 
> Is anyone else doing this self linking?
> 

I don't know, but it doesn't hurt. This way, if you're using git am
without b4 am -l (or forgot to add links manually), the history is still
pointed out by these self-reference links. I find it convenient and it
is a safeguard to not forget them, no matter who takes the patches.


Re: [PATCH v30 02/12] landlock: Add ruleset and domain management

2021-03-24 Thread James Morris
On Fri, 19 Mar 2021, Mickaël Salaün wrote:

> 
> >> Cc: Kees Cook 
> >> Signed-off-by: Mickaël Salaün 
> >> Acked-by: Serge Hallyn 
> >> Link: https://lore.kernel.org/r/20210316204252.427806-3-...@digikod.net
> > 
> > (Aside: you appear to be self-adding your Link: tags -- AIUI, this is
> > normally done by whoever pulls your series. I've only seen Link: tags
> > added when needing to refer to something else not included in the
> > series.)
> 
> It is an insurance to not lose history. :)

How will history be lost? The code is in the repo and discussions can 
easily be found by searching for subjects or message IDs.

Is anyone else doing this self linking?

-- 
James Morris



Re: [PATCH v30 02/12] landlock: Add ruleset and domain management

2021-03-22 Thread Jann Horn
On Tue, Mar 16, 2021 at 9:43 PM Mickaël Salaün  wrote:
> A Landlock ruleset is mainly a red-black tree with Landlock rules as
> nodes.  This enables quick update and lookup to match a requested
> access, e.g. to a file.  A ruleset is usable through a dedicated file
> descriptor (cf. following commit implementing syscalls) which enables a
> process to create and populate a ruleset with new rules.
>
> A domain is a ruleset tied to a set of processes.  This group of rules
> defines the security policy enforced on these processes and their future
> children.  A domain can transition to a new domain which is the
> intersection of all its constraints and those of a ruleset provided by
> the current process.  This modification only impact the current process.
> This means that a process can only gain more constraints (i.e. lose
> accesses) over time.
>
> Cc: James Morris 
> Cc: Jann Horn 
> Cc: Kees Cook 
> Signed-off-by: Mickaël Salaün 
> Acked-by: Serge Hallyn 
> Link: https://lore.kernel.org/r/20210316204252.427806-3-...@digikod.net

Reviewed-by: Jann Horn 


Re: [PATCH v30 02/12] landlock: Add ruleset and domain management

2021-03-19 Thread Kees Cook
On Fri, Mar 19, 2021 at 08:03:22PM +0100, Mickaël Salaün wrote:
> On 19/03/2021 19:40, Kees Cook wrote:
> > On Tue, Mar 16, 2021 at 09:42:42PM +0100, Mickaël Salaün wrote:
> >> [...]
> >> +static void put_rule(struct landlock_rule *const rule)
> >> +{
> >> +  might_sleep();
> >> +  if (!rule)
> >> +  return;
> >> +  landlock_put_object(rule->object);
> >> +  kfree(rule);
> >> +}
> > 
> > I'd expect this to be named "release" rather than "put" since it doesn't
> > do any lifetime reference counting.
> 
> It does decrement rule->object->usage .

Well, landlock_put_object() decrements rule->object's lifetime. It seems
"rule" doesn't have a lifetime. (There is no refcounter on rule.) I just
find it strange to see "put" without a matching "get". Not a big deal.

-- 
Kees Cook


Re: [PATCH v30 02/12] landlock: Add ruleset and domain management

2021-03-19 Thread Mickaël Salaün


On 19/03/2021 19:40, Kees Cook wrote:
> On Tue, Mar 16, 2021 at 09:42:42PM +0100, Mickaël Salaün wrote:
>> From: Mickaël Salaün 
>>
>> A Landlock ruleset is mainly a red-black tree with Landlock rules as
>> nodes.  This enables quick update and lookup to match a requested
>> access, e.g. to a file.  A ruleset is usable through a dedicated file
>> descriptor (cf. following commit implementing syscalls) which enables a
>> process to create and populate a ruleset with new rules.
>>
>> A domain is a ruleset tied to a set of processes.  This group of rules
>> defines the security policy enforced on these processes and their future
>> children.  A domain can transition to a new domain which is the
>> intersection of all its constraints and those of a ruleset provided by
>> the current process.  This modification only impact the current process.
>> This means that a process can only gain more constraints (i.e. lose
>> accesses) over time.
>>
>> Cc: James Morris 
>> Cc: Jann Horn 
>> Cc: Kees Cook 
>> Signed-off-by: Mickaël Salaün 
>> Acked-by: Serge Hallyn 
>> Link: https://lore.kernel.org/r/20210316204252.427806-3-...@digikod.net
> 
> (Aside: you appear to be self-adding your Link: tags -- AIUI, this is
> normally done by whoever pulls your series. I've only seen Link: tags
> added when needing to refer to something else not included in the
> series.)

It is an insurance to not lose history. :)

> 
>> [...]
>> +static void put_rule(struct landlock_rule *const rule)
>> +{
>> +might_sleep();
>> +if (!rule)
>> +return;
>> +landlock_put_object(rule->object);
>> +kfree(rule);
>> +}
> 
> I'd expect this to be named "release" rather than "put" since it doesn't
> do any lifetime reference counting.

It does decrement rule->object->usage .

> 
>> +static void build_check_ruleset(void)
>> +{
>> +const struct landlock_ruleset ruleset = {
>> +.num_rules = ~0,
>> +.num_layers = ~0,
>> +};
>> +
>> +BUILD_BUG_ON(ruleset.num_rules < LANDLOCK_MAX_NUM_RULES);
>> +BUILD_BUG_ON(ruleset.num_layers < LANDLOCK_MAX_NUM_LAYERS);
>> +}
> 
> This is checking that the largest possible stored value is correctly
> within the LANDLOCK_MAX_* macro value?

Yes, there is builtin checks for all Landlock limits.

> 
>> [...]
> 
> The locking all looks right, and given your test coverage and syzkaller
> work, it's hard for me to think of ways to prove it out any better. :)

Thanks!

> 
> Reviewed-by: Kees Cook 
> 
> 


Re: [PATCH v30 02/12] landlock: Add ruleset and domain management

2021-03-19 Thread Kees Cook
On Tue, Mar 16, 2021 at 09:42:42PM +0100, Mickaël Salaün wrote:
> From: Mickaël Salaün 
> 
> A Landlock ruleset is mainly a red-black tree with Landlock rules as
> nodes.  This enables quick update and lookup to match a requested
> access, e.g. to a file.  A ruleset is usable through a dedicated file
> descriptor (cf. following commit implementing syscalls) which enables a
> process to create and populate a ruleset with new rules.
> 
> A domain is a ruleset tied to a set of processes.  This group of rules
> defines the security policy enforced on these processes and their future
> children.  A domain can transition to a new domain which is the
> intersection of all its constraints and those of a ruleset provided by
> the current process.  This modification only impact the current process.
> This means that a process can only gain more constraints (i.e. lose
> accesses) over time.
> 
> Cc: James Morris 
> Cc: Jann Horn 
> Cc: Kees Cook 
> Signed-off-by: Mickaël Salaün 
> Acked-by: Serge Hallyn 
> Link: https://lore.kernel.org/r/20210316204252.427806-3-...@digikod.net

(Aside: you appear to be self-adding your Link: tags -- AIUI, this is
normally done by whoever pulls your series. I've only seen Link: tags
added when needing to refer to something else not included in the
series.)

> [...]
> +static void put_rule(struct landlock_rule *const rule)
> +{
> + might_sleep();
> + if (!rule)
> + return;
> + landlock_put_object(rule->object);
> + kfree(rule);
> +}

I'd expect this to be named "release" rather than "put" since it doesn't
do any lifetime reference counting.

> +static void build_check_ruleset(void)
> +{
> + const struct landlock_ruleset ruleset = {
> + .num_rules = ~0,
> + .num_layers = ~0,
> + };
> +
> + BUILD_BUG_ON(ruleset.num_rules < LANDLOCK_MAX_NUM_RULES);
> + BUILD_BUG_ON(ruleset.num_layers < LANDLOCK_MAX_NUM_LAYERS);
> +}

This is checking that the largest possible stored value is correctly
within the LANDLOCK_MAX_* macro value?

> [...]

The locking all looks right, and given your test coverage and syzkaller
work, it's hard for me to think of ways to prove it out any better. :)

Reviewed-by: Kees Cook 


-- 
Kees Cook


[PATCH v30 02/12] landlock: Add ruleset and domain management

2021-03-16 Thread Mickaël Salaün
From: Mickaël Salaün 

A Landlock ruleset is mainly a red-black tree with Landlock rules as
nodes.  This enables quick update and lookup to match a requested
access, e.g. to a file.  A ruleset is usable through a dedicated file
descriptor (cf. following commit implementing syscalls) which enables a
process to create and populate a ruleset with new rules.

A domain is a ruleset tied to a set of processes.  This group of rules
defines the security policy enforced on these processes and their future
children.  A domain can transition to a new domain which is the
intersection of all its constraints and those of a ruleset provided by
the current process.  This modification only impact the current process.
This means that a process can only gain more constraints (i.e. lose
accesses) over time.

Cc: James Morris 
Cc: Jann Horn 
Cc: Kees Cook 
Signed-off-by: Mickaël Salaün 
Acked-by: Serge Hallyn 
Link: https://lore.kernel.org/r/20210316204252.427806-3-...@digikod.net
---

Changes since v28:
* Add Acked-by Serge Hallyn.
* Clean up comment.

Changes since v27:
* Fix domains with layers of non-overlapping access rights.
* Add stricter limit checks (same semantic).
* Change the grow direction of a rule layer stack to make it the same as
  the new ruleset fs_access_masks stack (cosmetic change).
* Cosmetic fix for a comment block.

Changes since v26:
* Fix spelling.

Changes since v25:
* Add build-time checks for the num_layers and num_rules variables
  according to LANDLOCK_MAX_NUM_LAYERS and LANDLOCK_MAX_NUM_RULES, and
  move these limits to a dedicated file.
* Cosmetic variable renames.

Changes since v24:
* Update struct landlock_rule with a layer stack.  This reverts "Always
  intersect access rights" from v24 and also adds the ability to tie
  access rights with their policy layer.  As noted by Jann Horn, always
  intersecting access rights made some use cases uselessly more
  difficult to handle in user space.  Thanks to this new stack, we still
  have a deterministic policy behavior whatever their level in the stack
  of policies, while using a "union" of accesses when building a
  ruleset.  The implementation use a FAM to keep the access checks quick
  and memory efficient (4 bytes per layer per inode).  Update
  insert_rule() accordingly.

Changes since v23:
* Always intersect access rights.  Following the filesystem change
  logic, make ruleset updates more consistent by always intersecting
  access rights (boolean AND) instead of combining them (boolean OR) for
  the same layer.  This defensive approach could also help avoid user
  space to inadvertently allow multiple access rights for the same
  object (e.g.  write and execute access on a path hierarchy) instead of
  dealing with such inconsistency.  This can happen when there is no
  deduplication of objects (e.g. paths and underlying inodes) whereas
  they get different access rights with landlock_add_rule(2).
* Add extra checks to make sure that:
  - there is always an (allocated) object in each used rules;
  - when updating a ruleset with a new rule (i.e. not merging two
rulesets), the ruleset doesn't contain multiple layers.
* Hide merge parameter from the public landlock_insert_rule() API.  This
  helps avoid misuse of this function.
* Replace a remaining hardcoded 1 with SINGLE_DEPTH_NESTING.

Changes since v22:
* Explicitely use RB_ROOT and SINGLE_DEPTH_NESTING (suggested by Jann
  Horn).
* Improve comments and fix spelling (suggested by Jann Horn).

Changes since v21:
* Add and clean up comments.

Changes since v18:
* Account rulesets to kmemcg.
* Remove struct holes.
* Cosmetic changes.

Changes since v17:
* Move include/uapi/linux/landlock.h and _LANDLOCK_ACCESS_FS_* to a
  following patch.

Changes since v16:
* Allow enforcement of empty ruleset, which enables deny-all policies.

Changes since v15:
* Replace layer_levels and layer_depth with a bitfield of layers, cf.
  filesystem commit.
* Rename the LANDLOCK_ACCESS_FS_{UNLINK,RMDIR} with
  LANDLOCK_ACCESS_FS_REMOVE_{FILE,DIR} because it makes sense to use
  them for the action of renaming a file or a directory, which may lead
  to the removal of the source file or directory.  Removes the
  LANDLOCK_ACCESS_FS_{LINK_TO,RENAME_FROM,RENAME_TO} which are now
  replaced with LANDLOCK_ACCESS_FS_REMOVE_{FILE,DIR} and
  LANDLOCK_ACCESS_FS_MAKE_* .
* Update the documentation accordingly and highlight how the access
  rights are taken into account.
* Change nb_rules from atomic_t to u32 because it is not use anymore by
  show_fdinfo().
* Add safeguard for level variables types.
* Check max number of rules.
* Replace struct landlock_access (self and beneath bitfields) with one
  bitfield.
* Remove useless variable.
* Add comments.

Changes since v14:
* Simplify the object, rule and ruleset management at the expense of a
  less aggressive memory freeing (contributed by Jann Horn, with
  additional modifications):
  - Make a domain immutable (remove the opportunistic cleaning).
  - Remove RCU