linux-security-module.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] landlock: Use f_cred in security_file_open() hook
@ 2024-03-07  9:52 Mickaël Salaün
  2024-03-07 10:17 ` Christian Brauner
  2024-03-07 17:54 ` Kees Cook
  0 siblings, 2 replies; 4+ messages in thread
From: Mickaël Salaün @ 2024-03-07  9:52 UTC (permalink / raw)
  To: Christian Brauner, Günther Noack, Jann Horn, Paul Moore
  Cc: Mickaël Salaün, Kees Cook, Konstantin Meskhidze,
	Serge E . Hallyn, linux-kernel, linux-security-module

Use landlock_cred(file->f_cred)->domain instead of
landlock_get_current_domain() in security_file_open() hook
implementation.

This should not change the current behavior but could avoid potential
race conditions in case of current task's credentials change.

This will also ensure consistency with upcoming audit support relying on
file->f_cred.

Add and use a new get_fs_domain() helper to mask non-filesystem domains.

file->f_cred is set by path_openat()/alloc_empty_file()/init_file() just
before calling security_file_alloc().

Cc: Christian Brauner <brauner@kernel.org>
Cc: Günther Noack <gnoack@google.com>
Cc: Jann Horn <jannh@google.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Paul Moore <paul@paul-moore.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20240307095203.1467189-1-mic@digikod.net
---
 security/landlock/fs.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/security/landlock/fs.c b/security/landlock/fs.c
index 6f0bf1434a2c..c15559432d3d 100644
--- a/security/landlock/fs.c
+++ b/security/landlock/fs.c
@@ -248,15 +248,18 @@ get_handled_fs_accesses(const struct landlock_ruleset *const domain)
 	       LANDLOCK_ACCESS_FS_INITIALLY_DENIED;
 }
 
-static const struct landlock_ruleset *get_current_fs_domain(void)
+static const struct landlock_ruleset *
+get_fs_domain(const struct landlock_ruleset *const domain)
 {
-	const struct landlock_ruleset *const dom =
-		landlock_get_current_domain();
-
-	if (!dom || !get_raw_handled_fs_accesses(dom))
+	if (!domain || !get_raw_handled_fs_accesses(domain))
 		return NULL;
 
-	return dom;
+	return domain;
+}
+
+static const struct landlock_ruleset *get_current_fs_domain(void)
+{
+	return get_fs_domain(landlock_get_current_domain());
 }
 
 /*
@@ -1334,7 +1337,8 @@ static int hook_file_open(struct file *const file)
 	layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = {};
 	access_mask_t open_access_request, full_access_request, allowed_access;
 	const access_mask_t optional_access = LANDLOCK_ACCESS_FS_TRUNCATE;
-	const struct landlock_ruleset *const dom = get_current_fs_domain();
+	const struct landlock_ruleset *const dom =
+		get_fs_domain(landlock_cred(file->f_cred)->domain);
 
 	if (!dom)
 		return 0;
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] landlock: Use f_cred in security_file_open() hook
  2024-03-07  9:52 [PATCH] landlock: Use f_cred in security_file_open() hook Mickaël Salaün
@ 2024-03-07 10:17 ` Christian Brauner
  2024-03-07 15:16   ` Mickaël Salaün
  2024-03-07 17:54 ` Kees Cook
  1 sibling, 1 reply; 4+ messages in thread
From: Christian Brauner @ 2024-03-07 10:17 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Günther Noack, Jann Horn, Paul Moore, Kees Cook,
	Konstantin Meskhidze, Serge E . Hallyn, linux-kernel,
	linux-security-module

On Thu, Mar 07, 2024 at 10:52:03AM +0100, Mickaël Salaün wrote:
> Use landlock_cred(file->f_cred)->domain instead of
> landlock_get_current_domain() in security_file_open() hook
> implementation.
> 
> This should not change the current behavior but could avoid potential
> race conditions in case of current task's credentials change.

I have no problem with the patch but I'm curious how that credential
change could happen behind your back?

> 
> This will also ensure consistency with upcoming audit support relying on
> file->f_cred.
> 
> Add and use a new get_fs_domain() helper to mask non-filesystem domains.
> 
> file->f_cred is set by path_openat()/alloc_empty_file()/init_file() just
> before calling security_file_alloc().
> 
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Günther Noack <gnoack@google.com>
> Cc: Jann Horn <jannh@google.com>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Paul Moore <paul@paul-moore.com>
> Signed-off-by: Mickaël Salaün <mic@digikod.net>
> Link: https://lore.kernel.org/r/20240307095203.1467189-1-mic@digikod.net
> ---
>  security/landlock/fs.c | 18 +++++++++++-------
>  1 file changed, 11 insertions(+), 7 deletions(-)
> 
> diff --git a/security/landlock/fs.c b/security/landlock/fs.c
> index 6f0bf1434a2c..c15559432d3d 100644
> --- a/security/landlock/fs.c
> +++ b/security/landlock/fs.c
> @@ -248,15 +248,18 @@ get_handled_fs_accesses(const struct landlock_ruleset *const domain)
>  	       LANDLOCK_ACCESS_FS_INITIALLY_DENIED;
>  }
>  
> -static const struct landlock_ruleset *get_current_fs_domain(void)
> +static const struct landlock_ruleset *
> +get_fs_domain(const struct landlock_ruleset *const domain)
>  {
> -	const struct landlock_ruleset *const dom =
> -		landlock_get_current_domain();
> -
> -	if (!dom || !get_raw_handled_fs_accesses(dom))
> +	if (!domain || !get_raw_handled_fs_accesses(domain))
>  		return NULL;
>  
> -	return dom;
> +	return domain;
> +}
> +
> +static const struct landlock_ruleset *get_current_fs_domain(void)
> +{
> +	return get_fs_domain(landlock_get_current_domain());
>  }
>  
>  /*
> @@ -1334,7 +1337,8 @@ static int hook_file_open(struct file *const file)
>  	layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = {};
>  	access_mask_t open_access_request, full_access_request, allowed_access;
>  	const access_mask_t optional_access = LANDLOCK_ACCESS_FS_TRUNCATE;
> -	const struct landlock_ruleset *const dom = get_current_fs_domain();
> +	const struct landlock_ruleset *const dom =
> +		get_fs_domain(landlock_cred(file->f_cred)->domain);
>  
>  	if (!dom)
>  		return 0;
> -- 
> 2.44.0
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] landlock: Use f_cred in security_file_open() hook
  2024-03-07 10:17 ` Christian Brauner
@ 2024-03-07 15:16   ` Mickaël Salaün
  0 siblings, 0 replies; 4+ messages in thread
From: Mickaël Salaün @ 2024-03-07 15:16 UTC (permalink / raw)
  To: Christian Brauner, Paul Moore
  Cc: Günther Noack, Jann Horn, Kees Cook, Konstantin Meskhidze,
	Serge E . Hallyn, linux-kernel, linux-security-module

On Thu, Mar 07, 2024 at 11:17:13AM +0100, Christian Brauner wrote:
> On Thu, Mar 07, 2024 at 10:52:03AM +0100, Mickaël Salaün wrote:
> > Use landlock_cred(file->f_cred)->domain instead of
> > landlock_get_current_domain() in security_file_open() hook
> > implementation.
> > 
> > This should not change the current behavior but could avoid potential
> > race conditions in case of current task's credentials change.
> 
> I have no problem with the patch but I'm curious how that credential
> change could happen behind your back?

I hope nothing would change it (except maybe io_uring?), but it is
(more) atomic with the security_file_alloc() call and consistent with
Landlock's current (allowed_access) and future (f_cred) checks on files.

I chatted a bit with Paul and it resulted that is difficult to get
strong guarantees about credential consistency (i.e. following all call
sites).  Anyway, it also looks safer to follow the same approach as most
LSMs.

> 
> > 
> > This will also ensure consistency with upcoming audit support relying on
> > file->f_cred.
> > 
> > Add and use a new get_fs_domain() helper to mask non-filesystem domains.
> > 
> > file->f_cred is set by path_openat()/alloc_empty_file()/init_file() just
> > before calling security_file_alloc().
> > 
> > Cc: Christian Brauner <brauner@kernel.org>
> > Cc: Günther Noack <gnoack@google.com>
> > Cc: Jann Horn <jannh@google.com>
> > Cc: Kees Cook <keescook@chromium.org>
> > Cc: Paul Moore <paul@paul-moore.com>
> > Signed-off-by: Mickaël Salaün <mic@digikod.net>
> > Link: https://lore.kernel.org/r/20240307095203.1467189-1-mic@digikod.net
> > ---
> >  security/landlock/fs.c | 18 +++++++++++-------
> >  1 file changed, 11 insertions(+), 7 deletions(-)
> > 
> > diff --git a/security/landlock/fs.c b/security/landlock/fs.c
> > index 6f0bf1434a2c..c15559432d3d 100644
> > --- a/security/landlock/fs.c
> > +++ b/security/landlock/fs.c
> > @@ -248,15 +248,18 @@ get_handled_fs_accesses(const struct landlock_ruleset *const domain)
> >  	       LANDLOCK_ACCESS_FS_INITIALLY_DENIED;
> >  }
> >  
> > -static const struct landlock_ruleset *get_current_fs_domain(void)
> > +static const struct landlock_ruleset *
> > +get_fs_domain(const struct landlock_ruleset *const domain)
> >  {
> > -	const struct landlock_ruleset *const dom =
> > -		landlock_get_current_domain();
> > -
> > -	if (!dom || !get_raw_handled_fs_accesses(dom))
> > +	if (!domain || !get_raw_handled_fs_accesses(domain))
> >  		return NULL;
> >  
> > -	return dom;
> > +	return domain;
> > +}
> > +
> > +static const struct landlock_ruleset *get_current_fs_domain(void)
> > +{
> > +	return get_fs_domain(landlock_get_current_domain());
> >  }
> >  
> >  /*
> > @@ -1334,7 +1337,8 @@ static int hook_file_open(struct file *const file)
> >  	layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = {};
> >  	access_mask_t open_access_request, full_access_request, allowed_access;
> >  	const access_mask_t optional_access = LANDLOCK_ACCESS_FS_TRUNCATE;
> > -	const struct landlock_ruleset *const dom = get_current_fs_domain();
> > +	const struct landlock_ruleset *const dom =
> > +		get_fs_domain(landlock_cred(file->f_cred)->domain);
> >  
> >  	if (!dom)
> >  		return 0;
> > -- 
> > 2.44.0
> > 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] landlock: Use f_cred in security_file_open() hook
  2024-03-07  9:52 [PATCH] landlock: Use f_cred in security_file_open() hook Mickaël Salaün
  2024-03-07 10:17 ` Christian Brauner
@ 2024-03-07 17:54 ` Kees Cook
  1 sibling, 0 replies; 4+ messages in thread
From: Kees Cook @ 2024-03-07 17:54 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Christian Brauner, Günther Noack, Jann Horn, Paul Moore,
	Konstantin Meskhidze, Serge E . Hallyn, linux-kernel,
	linux-security-module

On Thu, Mar 07, 2024 at 10:52:03AM +0100, Mickaël Salaün wrote:
> Use landlock_cred(file->f_cred)->domain instead of
> landlock_get_current_domain() in security_file_open() hook
> implementation.
> 
> This should not change the current behavior but could avoid potential
> race conditions in case of current task's credentials change.
> 
> This will also ensure consistency with upcoming audit support relying on
> file->f_cred.
> 
> Add and use a new get_fs_domain() helper to mask non-filesystem domains.
> 
> file->f_cred is set by path_openat()/alloc_empty_file()/init_file() just
> before calling security_file_alloc().
> 
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Günther Noack <gnoack@google.com>
> Cc: Jann Horn <jannh@google.com>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Paul Moore <paul@paul-moore.com>
> Signed-off-by: Mickaël Salaün <mic@digikod.net>
> Link: https://lore.kernel.org/r/20240307095203.1467189-1-mic@digikod.net

This looks sensible to me. It follows best practices[1] for avoiding
confused deputy attacks as well.

Reviewed-by: Kees Cook <keescook@chromium.org>

[1] https://docs.kernel.org/security/credentials.html?highlight=confused+deputy#open-file-credentials

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-03-07 17:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-07  9:52 [PATCH] landlock: Use f_cred in security_file_open() hook Mickaël Salaün
2024-03-07 10:17 ` Christian Brauner
2024-03-07 15:16   ` Mickaël Salaün
2024-03-07 17:54 ` Kees Cook

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).