[Acked] [Prereq X/T] Make file credentials available to the seqfile interfaces
Andy Whitcroft
apw at canonical.com
Thu Jun 22 08:38:01 UTC 2017
On Thu, Jun 22, 2017 at 08:54:59AM +0200, Stefan Bader wrote:
> From: Linus Torvalds <torvalds at linux-foundation.org>
>
> A lot of seqfile users seem to be using things like %pK that uses the
> credentials of the current process, but that is actually completely
> wrong for filesystem interfaces.
>
> The unix semantics for permission checking files is to check permissions
> at _open_ time, not at read or write time, and that is not just a small
> detail: passing off stdin/stdout/stderr to a suid application and making
> the actual IO happen in privileged context is a classic exploit
> technique.
>
> So if we want to be able to look at permissions at read time, we need to
> use the file open credentials, not the current ones. Normal file
> accesses can just use "f_cred" (or any of the helper functions that do
> that, like file_ns_capable()), but the seqfile interfaces do not have
> any such options.
>
> It turns out that seq_file _does_ save away the user_ns information of
> the file, though. Since user_ns is just part of the full credential
> information, replace that special case with saving off the cred pointer
> instead, and suddenly seq_file has all the permission information it
> needs.
>
> Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
>
> CVE-2015-8944
>
> (cherry-picked from commit 34dbbcdbf63360661ff7bda6c5f52f99ac515f92)
> Signed-off-by: Stefan Bader <stefan.bader at canonical.com>
> ---
>
> This patch is required as pre-requisity to resolve the FTBS. It is
> a cherry-pick on both Xenial and Trusty, however for Trusty it has
> to be applied with -C2.
> Compile tested both applied together on Xenial and Trusty.
>
> -Stefan
>
>
> fs/seq_file.c | 7 ++++---
> include/linux/seq_file.h | 13 ++++---------
> 2 files changed, 8 insertions(+), 12 deletions(-)
>
> diff --git a/fs/seq_file.c b/fs/seq_file.c
> index e85664b..19f532e 100644
> --- a/fs/seq_file.c
> +++ b/fs/seq_file.c
> @@ -72,9 +72,10 @@ int seq_open(struct file *file, const struct seq_operations *op)
>
> mutex_init(&p->lock);
> p->op = op;
> -#ifdef CONFIG_USER_NS
> - p->user_ns = file->f_cred->user_ns;
> -#endif
> +
> + // No refcounting: the lifetime of 'p' is constrained
> + // to the lifetime of the file.
> + p->file = file;
>
> /*
> * Wrappers around seq_open(e.g. swaps_open) need to be
> diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
> index dde00de..f3d45dd 100644
> --- a/include/linux/seq_file.h
> +++ b/include/linux/seq_file.h
> @@ -7,13 +7,10 @@
> #include <linux/mutex.h>
> #include <linux/cpumask.h>
> #include <linux/nodemask.h>
> +#include <linux/fs.h>
> +#include <linux/cred.h>
>
> struct seq_operations;
> -struct file;
> -struct path;
> -struct inode;
> -struct dentry;
> -struct user_namespace;
>
> struct seq_file {
> char *buf;
> @@ -27,9 +24,7 @@ struct seq_file {
> struct mutex lock;
> const struct seq_operations *op;
> int poll_event;
> -#ifdef CONFIG_USER_NS
> - struct user_namespace *user_ns;
> -#endif
> + const struct file *file;
> void *private;
> };
>
> @@ -147,7 +142,7 @@ int seq_release_private(struct inode *, struct file *);
> static inline struct user_namespace *seq_user_ns(struct seq_file *seq)
> {
> #ifdef CONFIG_USER_NS
> - return seq->user_ns;
> + return seq->file->f_cred->user_ns;
> #else
> extern struct user_namespace init_user_ns;
> return &init_user_ns;
Looks very simple. Clean cherry-pick. Looks to do what is claimed.
Acked-by: Andy Whitcroft <apw at canonical.com>
-apw
More information about the kernel-team
mailing list