* Re: [PATCH] arch: uapi: asm: mman.h: Let MADV_FREE have same value for all architectures
From: Chen Gang @ 2014-12-10 1:45 UTC (permalink / raw)
To: akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org
Cc: Minchan Kim, rth-hL46jP5Bxq7R7s880joybQ@public.gmane.org,
ink-biIs/Y0ymYJMZLIVYojuPNP0rXTJTi09@public.gmane.org,
mattst88-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org, Ralf Baechle,
jejb-6jwH94ZQLHl74goWV3ctuw@public.gmane.org,
deller-Mmb7MZpHnFY@public.gmane.org,
chris-YvXeqwSYzG2sTnJN9+BGXg@public.gmane.org,
jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org, Arnd Bergmann,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arch-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven,
Carlos O'Donell, Darrick J. Wong, dietlibc-a6ha8lKT7ZQ,
Felix von Leitner
In-Reply-To: <54822B19.2070804-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Hello Andrew:
Could you help check this patch, when you have time. And apply it if
possible.
I guess, this patch is a little urgent, since it changes uapi, if wait
a little longer, more user mode programs (e.g. libc) may use MADV_FREE
as various values.
Thanks.
On 12/6/14 06:00, Chen Gang wrote:
> On 12/05/2014 02:54 PM, Minchan Kim wrote:
>> On Fri, Dec 05, 2014 at 06:58:29AM +0800, Chen Gang wrote:
>>> For uapi, need try to let all macros have same value, and MADV_FREE is
>>> added into main branch recently, so need redefine MADV_FREE for it.
>>>
>>> At present, '8' can be shared with all architectures, so redefine it to
>>> '8'.
>>>
>>> Signed-off-by: Chen Gang <gang.chen.5i5j-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>
>>
>> Hello Chen,
>>
>> Thanks for looking at this.
>> Feel free to add my sign.
>>
>> Acked-by: Minchan Kim <minchan-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>>
>
> OK, thanks.
>
> Originally I sent the same patch like you sent (but later than yours).
> Geert suggested to use same value for MADV_FREE, and Carlos confirmed
> it and suggested more things (sorry, I forgot to Cc them in this mail).
>
--
Chen Gang
Open, share, and attitude like air, water, and life which God blessed
^ permalink raw reply
* Re: [CFT][PATCH 7/8] userns: Add a knob to disable setgroups on a per user namespace basis
From: Andy Lutomirski @ 2014-12-10 0:21 UTC (permalink / raw)
To: Eric W.Biederman
Cc: Linux Containers, Josh Triplett, Andrew Morton, Kees Cook,
Michael Kerrisk-manpages, Linux API, linux-man,
linux-kernel@vger.kernel.org, LSM, Casey Schaufler,
Serge E. Hallyn, Richard Weinberger, Kenton Varda, stable
In-Reply-To: <971ad3f6-90fd-4e3f-916c-8988af3c826d@email.android.com>
On Tue, Dec 9, 2014 at 4:04 PM, Eric W.Biederman <ebiederm@xmission.com> wrote:
>
>
> On December 9, 2014 4:28:38 PM CST, Andy Lutomirski <luto@amacapital.net> wrote:
>>On Tue, Dec 9, 2014 at 12:42 PM, Eric W. Biederman
>><ebiederm@xmission.com> wrote:
>>>
>>> - Expose the knob to user space through a proc file
>>/proc/<pid>/setgroups
>>>
>>> A value of "deny" means the setgroups system call is disabled in
>>the
>>> current processes user namespace and can not be enabled in the
>>> future in this user namespace.
>>>
>>> A value of "allow" means the segtoups system call is enabled.
>>>
>>> - Descendant user namespaces inherit the value of setgroups from
>>> their parents.
>>>
>>> - A proc file is used (instead of a sysctl) as sysctls
>>> currently do not pass in a struct file so file_ns_capable
>>> is unusable.
>>
>>Reviewed-by: Andy Lutomirski <luto@amacapital.net>
>>
>>But I still don't like the name "setgroups". People may look at that
>>and have no clue what the scope of the setting is. And anyone who, as
>>root, writes "deny" to /proc/self/setgroups, thinking that it acts on
>>self, will be in for a surprise.
>
> True setgroups isn't perfect. Documenting it in a manpage may have to be enough. The only real improvement I can think of would be to make the setting a sysctl. But I think pursuing that approaches the point where perfection is the enemy of getting this problem fixed.
>
Would "userns_setgroups" be okay?
--Andy
> Eric
--
Andy Lutomirski
AMA Capital Management, LLC
^ permalink raw reply
* Re: [CFT][PATCH 7/8] userns: Add a knob to disable setgroups on a per user namespace basis
From: Eric W.Biederman @ 2014-12-10 0:04 UTC (permalink / raw)
To: Andy Lutomirski
Cc: linux-man, Kees Cook, Linux API, Linux Containers, Josh Triplett,
stable, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Kenton Varda, LSM, Michael Kerrisk-manpages, Richard Weinberger,
Casey Schaufler, Andrew Morton
In-Reply-To: <CALCETrVfKiXuY=KY_=nHpkTyLWgpy_3DK=4Mr2mhpyX9z1TzrA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On December 9, 2014 4:28:38 PM CST, Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org> wrote:
>On Tue, Dec 9, 2014 at 12:42 PM, Eric W. Biederman
><ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> wrote:
>>
>> - Expose the knob to user space through a proc file
>/proc/<pid>/setgroups
>>
>> A value of "deny" means the setgroups system call is disabled in
>the
>> current processes user namespace and can not be enabled in the
>> future in this user namespace.
>>
>> A value of "allow" means the segtoups system call is enabled.
>>
>> - Descendant user namespaces inherit the value of setgroups from
>> their parents.
>>
>> - A proc file is used (instead of a sysctl) as sysctls
>> currently do not pass in a struct file so file_ns_capable
>> is unusable.
>
>Reviewed-by: Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>
>
>But I still don't like the name "setgroups". People may look at that
>and have no clue what the scope of the setting is. And anyone who, as
>root, writes "deny" to /proc/self/setgroups, thinking that it acts on
>self, will be in for a surprise.
True setgroups isn't perfect. Documenting it in a manpage may have to be enough. The only real improvement I can think of would be to make the setting a sysctl. But I think pursuing that approaches the point where perfection is the enemy of getting this problem fixed.
Eric
^ permalink raw reply
* Re: [CFT][PATCH 3/8] userns: Don't allow unprivileged creation of gid mappings
From: Andy Lutomirski @ 2014-12-09 23:00 UTC (permalink / raw)
To: Eric W. Biederman
Cc: linux-man, Kees Cook, Linux API, Linux Containers, Josh Triplett,
stable, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Kenton Varda, LSM, Michael Kerrisk-manpages, Richard Weinberger,
Casey Schaufler, Andrew Morton
In-Reply-To: <874mt4lfr6.fsf_-_-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
On Tue, Dec 9, 2014 at 12:39 PM, Eric W. Biederman
<ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> wrote:
>
> As any gid mapping will allow and must allow for backwards
> compatibility dropping groups don't allow any gid mappings to be
> established without CAP_SETGID in the parent user namespace.
>
> For a small class of applications this change breaks userspace
> and removes useful functionality. This small class of applications
> includes tools/testing/selftests/mount/unprivilged-remount-test.c
>
> Most of the removed functionality will be added back with the addition
> of a one way knob to disable setgroups. Once setgroups is disabled
> setting the gid_map becomes as safe as setting the uid_map.
>
> For more common applications that set the uid_map and the gid_map
> with privilege this change will have no affect.
>
Reviewed-by: Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>
> This is part of a fix for CVE-2014-8989.
>
> Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
> ---
> kernel/user_namespace.c | 4 ----
> 1 file changed, 4 deletions(-)
>
> diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
> index 27c8dab48c07..1ce6d67c07b7 100644
> --- a/kernel/user_namespace.c
> +++ b/kernel/user_namespace.c
> @@ -821,10 +821,6 @@ static bool new_idmap_permitted(const struct file *file,
> kuid_t uid = make_kuid(ns->parent, id);
> if (uid_eq(uid, file->f_cred->fsuid))
> return true;
> - } else if (cap_setid == CAP_SETGID) {
> - kgid_t gid = make_kgid(ns->parent, id);
> - if (gid_eq(gid, file->f_cred->fsgid))
> - return true;
> }
> }
>
> --
> 1.9.1
>
--
Andy Lutomirski
AMA Capital Management, LLC
^ permalink raw reply
* Re: [v8 4/5] ext4: adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR interface support
From: Dave Chinner @ 2014-12-09 22:57 UTC (permalink / raw)
To: Li Xi
Cc: linux-fsdevel, linux-ext4, linux-api, tytso, adilger, jack, viro,
hch, dmonakhov
In-Reply-To: <1418102548-5469-5-git-send-email-lixi@ddn.com>
On Tue, Dec 09, 2014 at 01:22:27PM +0800, Li Xi wrote:
> This patch adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR ioctl interface
> support for ext4. The interface is kept consistent with
> XFS_IOC_FSGETXATTR/XFS_IOC_FSGETXATTR.
>
> Signed-off-by: Li Xi <lixi@ddn.com>
> ---
> fs/ext4/ext4.h | 111 ++++++++++++++++
> fs/ext4/ioctl.c | 330 +++++++++++++++++++++++++++++++++--------------
> fs/xfs/xfs_fs.h | 47 +++-----
> include/uapi/linux/fs.h | 58 ++++++++
> 4 files changed, 418 insertions(+), 128 deletions(-)
>
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index 136e18c..43a2a88 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -384,6 +384,115 @@ struct flex_groups {
> #define EXT4_FL_USER_VISIBLE 0x204BDFFF /* User visible flags */
> #define EXT4_FL_USER_MODIFIABLE 0x204380FF /* User modifiable flags */
>
> +/* Transfer internal flags to xflags */
> +static inline __u32 ext4_iflags_to_xflags(unsigned long iflags)
> +{
> + __u32 xflags = 0;
> +
> + if (iflags & EXT4_SECRM_FL)
> + xflags |= FS_XFLAG_SECRM;
> + if (iflags & EXT4_UNRM_FL)
> + xflags |= FS_XFLAG_UNRM;
> + if (iflags & EXT4_COMPR_FL)
> + xflags |= FS_XFLAG_COMPR;
....
NACK.
> + if (iflags & EXT4_SYNC_FL)
> + xflags |= FS_XFLAG_SYNC;
> + if (iflags & EXT4_IMMUTABLE_FL)
> + xflags |= FS_XFLAG_IMMUTABLE;
> + if (iflags & EXT4_APPEND_FL)
> + xflags |= FS_XFLAG_APPEND;
> + if (iflags & EXT4_NODUMP_FL)
> + xflags |= FS_XFLAG_NODUMP;
> + if (iflags & EXT4_NOATIME_FL)
> + xflags |= FS_XFLAG_NOATIME;
These are OK because they already exist in the interface, but all
the ext4 specific flags you've added have no place in this patchset.
> +
> /* Flags that should be inherited by new inodes from their parent. */
> #define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\
> EXT4_SYNC_FL | EXT4_NODUMP_FL | EXT4_NOATIME_FL |\
> @@ -606,6 +715,8 @@ enum {
> #define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64)
> #define EXT4_IOC_SWAP_BOOT _IO('f', 17)
> #define EXT4_IOC_PRECACHE_EXTENTS _IO('f', 18)
> +#define EXT4_IOC_FSGETXATTR FS_IOC_FSGETXATTR
> +#define EXT4_IOC_FSSETXATTR FS_IOC_FSSETXATTR
NACK. Userspace only needs FS_IOC_FS[GS]ETXATTR so that it works across
all filesystems. We need to retain XFS_IOC_FS[GS]ETXATTR so we
don't break existing userspace tools, but we do not need new
filesystem specific definitions anywhere.
> diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
> index fcbf647..872fed5 100644
> --- a/include/uapi/linux/fs.h
> +++ b/include/uapi/linux/fs.h
> @@ -58,6 +58,62 @@ struct inodes_stat_t {
> long dummy[5]; /* padding for sysctl ABI compatibility */
> };
>
> +/*
> + * Extend attribute flags. These should be or-ed together to figure out what
> + * is valid.
> + */
> +#define FSX_XFLAGS (1 << 0)
> +#define FSX_EXTSIZE (1 << 1)
> +#define FSX_NEXTENTS (1 << 2)
> +#define FSX_PROJID (1 << 3)
NACK.
I've said this more than once: these are *private to XFS's
implementation* and are not be part of the user interface. Do not
move them from their existing location.
> +
> +/*
> + * Structure for FS_IOC_FSGETXATTR and FS_IOC_FSSETXATTR.
> + */
> +struct fsxattr {
> + __u32 fsx_xflags; /* xflags field value (get/set) */
> + __u32 fsx_extsize; /* extsize field value (get/set)*/
> + __u32 fsx_nextents; /* nextents field value (get) */
> + __u32 fsx_projid; /* project identifier (get/set) */
> + unsigned char fsx_pad[12];
> +};
> +
> +/*
> + * Flags for the fsx_xflags field
> + */
> +#define FS_XFLAG_REALTIME 0x00000001 /* data in realtime volume */
> +#define FS_XFLAG_PREALLOC 0x00000002 /* preallocated file extents */
> +#define FS_XFLAG_SECRM 0x00000004 /* secure deletion */
NACK - ext4 specific.
> +#define FS_XFLAG_IMMUTABLE 0x00000008 /* file cannot be modified */
> +#define FS_XFLAG_APPEND 0x00000010 /* all writes append */
> +#define FS_XFLAG_SYNC 0x00000020 /* all writes synchronous */
> +#define FS_XFLAG_NOATIME 0x00000040 /* do not update access time */
> +#define FS_XFLAG_NODUMP 0x00000080 /* do not include in backups */
> +#define FS_XFLAG_RTINHERIT 0x00000100 /* create with rt bit set */
> +#define FS_XFLAG_PROJINHERIT 0x00000200 /* create with parents projid */
> +#define FS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */
> +#define FS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
> +#define FS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
> +#define FS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
> +#define FS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */
existing flags.
> +#define FS_XFLAG_UNRM 0x00008000 /* undelete */
> +#define FS_XFLAG_COMPR 0x00010000 /* compress file */
> +#define FS_XFLAG_COMPRBLK 0x00020000 /* one or more compressed clusters */
> +#define FS_XFLAG_NOCOMPR 0x00040000 /* don't compress */
> +#define FS_XFLAG_ECOMPR 0x00080000 /* compression error */
> +#define FS_XFLAG_INDEX 0x00100000 /* hash-indexed directory */
> +#define FS_XFLAG_IMAGIC 0x00200000 /* AFS directory */
> +#define FS_XFLAG_JOURNAL_DATA 0x00400000 /* file data should be journaled */
> +#define FS_XFLAG_NOTAIL 0x00800000 /* file tail should not be merged */
> +#define FS_XFLAG_DIRSYNC 0x01000000 /* dirsync behaviour (directories only) */
> +#define FS_XFLAG_TOPDIR 0x02000000 /* top of directory hierarchies*/
> +#define FS_XFLAG_HUGE_FILE 0x04000000 /* set to each huge file */
> +#define FS_XFLAG_EXTENTS 0x08000000 /* inode uses extents */
> +#define FS_XFLAG_EA_INODE 0x10000000 /* inode used for large EA */
> +#define FS_XFLAG_EOFBLOCKS 0x20000000 /* blocks allocated beyond EOF */
> +#define FS_XFLAG_INLINE_DATA 0x40000000 /* inode has inline data. */
And a bunch more ext4 specific flags that *uses all the remaining
flag space*. At minimum, we need to keep space in this existing
flags field for flags to future indication of how the padding is
used, so that's yet another NACK.
Further, none of these have any relevance to project quotas so
should not be a part of this patchset. Nor are they relevant to any
other filesystem, and many are duplicated by information you can get
from FIEMAP and other interfaces. NACK, again.
Because I'm getting annoyed at being repeatedly ignored about what
needs to be done here, I'm now going to shout a bit. DO NOT CHANGE
THE INTERFACE. DO NOT ADD any new flags to the interface. DO NOT
REDEFINE how the interface works. DO NOT "ext4-ise" the interface.
The only changes to the interface code should be moving the XFS
definitions and renaming them so as to provide the new generic
ioctl definition as well as the historic XFS definitions. The ext4
implementation needs to be done in a separate patch to the interface
rename, and it must only implement the functionality the interface
already provides. Anything else is outside the scope of this
patchset and requires separate discussion.
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
^ permalink raw reply
* Re: [CFT][PATCH 6/8] userns: Rename id_map_mutex to userns_state_mutex
From: Andy Lutomirski @ 2014-12-09 22:49 UTC (permalink / raw)
To: Eric W. Biederman
Cc: linux-man, Kees Cook, Linux API, Linux Containers, Josh Triplett,
stable, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Kenton Varda, LSM, Michael Kerrisk-manpages, Richard Weinberger,
Casey Schaufler, Andrew Morton
In-Reply-To: <87mw6wk12i.fsf_-_-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
On Tue, Dec 9, 2014 at 12:41 PM, Eric W. Biederman
<ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> wrote:
>
> Generalize id_map_mutex so it can be used for more state of a user namespace.
Reviewed-by: Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>
>
> Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
> ---
> kernel/user_namespace.c | 14 ++++++--------
> 1 file changed, 6 insertions(+), 8 deletions(-)
>
> diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
> index 1e34de2fbd60..44a555ac6104 100644
> --- a/kernel/user_namespace.c
> +++ b/kernel/user_namespace.c
> @@ -24,6 +24,7 @@
> #include <linux/fs_struct.h>
>
> static struct kmem_cache *user_ns_cachep __read_mostly;
> +static DEFINE_MUTEX(userns_state_mutex);
>
> static bool new_idmap_permitted(const struct file *file,
> struct user_namespace *ns, int cap_setid,
> @@ -583,9 +584,6 @@ static bool mappings_overlap(struct uid_gid_map *new_map,
> return false;
> }
>
> -
> -static DEFINE_MUTEX(id_map_mutex);
> -
> static ssize_t map_write(struct file *file, const char __user *buf,
> size_t count, loff_t *ppos,
> int cap_setid,
> @@ -602,7 +600,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
> ssize_t ret = -EINVAL;
>
> /*
> - * The id_map_mutex serializes all writes to any given map.
> + * The userns_state_mutex serializes all writes to any given map.
> *
> * Any map is only ever written once.
> *
> @@ -620,7 +618,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
> * order and smp_rmb() is guaranteed that we don't have crazy
> * architectures returning stale data.
> */
> - mutex_lock(&id_map_mutex);
> + mutex_lock(&userns_state_mutex);
>
> ret = -EPERM;
> /* Only allow one successful write to the map */
> @@ -750,7 +748,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
> *ppos = count;
> ret = count;
> out:
> - mutex_unlock(&id_map_mutex);
> + mutex_unlock(&userns_state_mutex);
> if (page)
> free_page(page);
> return ret;
> @@ -845,12 +843,12 @@ bool userns_may_setgroups(const struct user_namespace *ns)
> {
> bool allowed;
>
> - mutex_lock(&id_map_mutex);
> + mutex_lock(&userns_state_mutex);
> /* It is not safe to use setgroups until a gid mapping in
> * the user namespace has been established.
> */
> allowed = ns->gid_map.nr_extents != 0;
> - mutex_unlock(&id_map_mutex);
> + mutex_unlock(&userns_state_mutex);
>
> return allowed;
> }
> --
> 1.9.1
>
--
Andy Lutomirski
AMA Capital Management, LLC
^ permalink raw reply
* Re: [CFT][PATCH 2/8] userns: Don't allow setgroups until a gid mapping has been setablished
From: Andy Lutomirski @ 2014-12-09 22:49 UTC (permalink / raw)
To: Eric W. Biederman
Cc: linux-man, Kees Cook, Linux API, Linux Containers, Josh Triplett,
stable, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Kenton Varda, LSM, Michael Kerrisk-manpages, Richard Weinberger,
Casey Schaufler, Andrew Morton
In-Reply-To: <87d27slfsw.fsf_-_-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
On Tue, Dec 9, 2014 at 12:38 PM, Eric W. Biederman
<ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> wrote:
>
> setgroups is unique in not needing a valid mapping before it can be called,
> in the case of setgroups(0, NULL) which drops all supplemental groups.
>
> The design of the user namespace assumes that CAP_SETGID can not actually
> be used until a gid mapping is established. Therefore add a helper function
> to see if the user namespace gid mapping has been established and call
> that function in the setgroups permission check.
>
> This is part of the fix for CVE-2014-8989, being able to drop groups
> without privilege using user namespaces.
Reviewed-by: Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>
>
> Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
> ---
> include/linux/user_namespace.h | 5 +++++
> kernel/groups.c | 4 +++-
> kernel/user_namespace.c | 14 ++++++++++++++
> 3 files changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
> index e95372654f09..8d493083486a 100644
> --- a/include/linux/user_namespace.h
> +++ b/include/linux/user_namespace.h
> @@ -63,6 +63,7 @@ extern const struct seq_operations proc_projid_seq_operations;
> extern ssize_t proc_uid_map_write(struct file *, const char __user *, size_t, loff_t *);
> extern ssize_t proc_gid_map_write(struct file *, const char __user *, size_t, loff_t *);
> extern ssize_t proc_projid_map_write(struct file *, const char __user *, size_t, loff_t *);
> +extern bool userns_may_setgroups(const struct user_namespace *ns);
> #else
>
> static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
> @@ -87,6 +88,10 @@ static inline void put_user_ns(struct user_namespace *ns)
> {
> }
>
> +static inline bool userns_may_setgroups(const struct user_namespace *ns)
> +{
> + return true;
> +}
> #endif
>
> #endif /* _LINUX_USER_H */
> diff --git a/kernel/groups.c b/kernel/groups.c
> index 02d8a251c476..664411f171b5 100644
> --- a/kernel/groups.c
> +++ b/kernel/groups.c
> @@ -6,6 +6,7 @@
> #include <linux/slab.h>
> #include <linux/security.h>
> #include <linux/syscalls.h>
> +#include <linux/user_namespace.h>
> #include <asm/uaccess.h>
>
> /* init to 2 - one for init_task, one to ensure it is never freed */
> @@ -217,7 +218,8 @@ bool may_setgroups(void)
> {
> struct user_namespace *user_ns = current_user_ns();
>
> - return ns_capable(user_ns, CAP_SETGID);
> + return ns_capable(user_ns, CAP_SETGID) &&
> + userns_may_setgroups(user_ns);
> }
>
> /*
> diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
> index b99c862a2e3f..27c8dab48c07 100644
> --- a/kernel/user_namespace.c
> +++ b/kernel/user_namespace.c
> @@ -843,6 +843,20 @@ static bool new_idmap_permitted(const struct file *file,
> return false;
> }
>
> +bool userns_may_setgroups(const struct user_namespace *ns)
> +{
> + bool allowed;
> +
> + mutex_lock(&id_map_mutex);
> + /* It is not safe to use setgroups until a gid mapping in
> + * the user namespace has been established.
> + */
> + allowed = ns->gid_map.nr_extents != 0;
> + mutex_unlock(&id_map_mutex);
> +
> + return allowed;
> +}
> +
> static void *userns_get(struct task_struct *task)
> {
> struct user_namespace *user_ns;
> --
> 1.9.1
>
--
Andy Lutomirski
AMA Capital Management, LLC
^ permalink raw reply
* Re: [CFT][PATCH 7/8] userns: Add a knob to disable setgroups on a per user namespace basis
From: Andy Lutomirski @ 2014-12-09 22:28 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Linux Containers, Josh Triplett, Andrew Morton, Kees Cook,
Michael Kerrisk-manpages, Linux API, linux-man,
linux-kernel@vger.kernel.org, LSM, Casey Schaufler,
Serge E. Hallyn, Richard Weinberger, Kenton Varda, stable
In-Reply-To: <87fvcok11h.fsf_-_@x220.int.ebiederm.org>
On Tue, Dec 9, 2014 at 12:42 PM, Eric W. Biederman
<ebiederm@xmission.com> wrote:
>
> - Expose the knob to user space through a proc file /proc/<pid>/setgroups
>
> A value of "deny" means the setgroups system call is disabled in the
> current processes user namespace and can not be enabled in the
> future in this user namespace.
>
> A value of "allow" means the segtoups system call is enabled.
>
> - Descendant user namespaces inherit the value of setgroups from
> their parents.
>
> - A proc file is used (instead of a sysctl) as sysctls
> currently do not pass in a struct file so file_ns_capable
> is unusable.
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
But I still don't like the name "setgroups". People may look at that
and have no clue what the scope of the setting is. And anyone who, as
root, writes "deny" to /proc/self/setgroups, thinking that it acts on
self, will be in for a surprise.
--Andy
>
> Cc: stable@vger.kernel.org
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
> fs/proc/base.c | 31 +++++++++----
> include/linux/user_namespace.h | 7 +++
> kernel/user.c | 1 +
> kernel/user_namespace.c | 103 +++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 134 insertions(+), 8 deletions(-)
>
> diff --git a/fs/proc/base.c b/fs/proc/base.c
> index 772efa45a452..4ebed9f01d97 100644
> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -2386,7 +2386,7 @@ static int proc_tgid_io_accounting(struct seq_file *m, struct pid_namespace *ns,
> #endif /* CONFIG_TASK_IO_ACCOUNTING */
>
> #ifdef CONFIG_USER_NS
> -static int proc_id_map_open(struct inode *inode, struct file *file,
> +static int proc_userns_open(struct inode *inode, struct file *file,
> const struct seq_operations *seq_ops)
> {
> struct user_namespace *ns = NULL;
> @@ -2418,7 +2418,7 @@ err:
> return ret;
> }
>
> -static int proc_id_map_release(struct inode *inode, struct file *file)
> +static int proc_userns_release(struct inode *inode, struct file *file)
> {
> struct seq_file *seq = file->private_data;
> struct user_namespace *ns = seq->private;
> @@ -2428,17 +2428,17 @@ static int proc_id_map_release(struct inode *inode, struct file *file)
>
> static int proc_uid_map_open(struct inode *inode, struct file *file)
> {
> - return proc_id_map_open(inode, file, &proc_uid_seq_operations);
> + return proc_userns_open(inode, file, &proc_uid_seq_operations);
> }
>
> static int proc_gid_map_open(struct inode *inode, struct file *file)
> {
> - return proc_id_map_open(inode, file, &proc_gid_seq_operations);
> + return proc_userns_open(inode, file, &proc_gid_seq_operations);
> }
>
> static int proc_projid_map_open(struct inode *inode, struct file *file)
> {
> - return proc_id_map_open(inode, file, &proc_projid_seq_operations);
> + return proc_userns_open(inode, file, &proc_projid_seq_operations);
> }
>
> static const struct file_operations proc_uid_map_operations = {
> @@ -2446,7 +2446,7 @@ static const struct file_operations proc_uid_map_operations = {
> .write = proc_uid_map_write,
> .read = seq_read,
> .llseek = seq_lseek,
> - .release = proc_id_map_release,
> + .release = proc_userns_release,
> };
>
> static const struct file_operations proc_gid_map_operations = {
> @@ -2454,7 +2454,7 @@ static const struct file_operations proc_gid_map_operations = {
> .write = proc_gid_map_write,
> .read = seq_read,
> .llseek = seq_lseek,
> - .release = proc_id_map_release,
> + .release = proc_userns_release,
> };
>
> static const struct file_operations proc_projid_map_operations = {
> @@ -2462,7 +2462,20 @@ static const struct file_operations proc_projid_map_operations = {
> .write = proc_projid_map_write,
> .read = seq_read,
> .llseek = seq_lseek,
> - .release = proc_id_map_release,
> + .release = proc_userns_release,
> +};
> +
> +static int proc_setgroups_open(struct inode *inode, struct file *file)
> +{
> + return proc_userns_open(inode, file, &proc_setgroups_seq_operations);
> +}
> +
> +static const struct file_operations proc_setgroups_operations = {
> + .open = proc_setgroups_open,
> + .write = proc_setgroups_write,
> + .read = seq_read,
> + .llseek = seq_lseek,
> + .release = proc_userns_release,
> };
> #endif /* CONFIG_USER_NS */
>
> @@ -2572,6 +2585,7 @@ static const struct pid_entry tgid_base_stuff[] = {
> REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations),
> REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations),
> REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
> + REG("setgroups", S_IRUGO|S_IWUSR, proc_setgroups_operations),
> #endif
> #ifdef CONFIG_CHECKPOINT_RESTORE
> REG("timers", S_IRUGO, proc_timers_operations),
> @@ -2913,6 +2927,7 @@ static const struct pid_entry tid_base_stuff[] = {
> REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations),
> REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations),
> REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
> + REG("setgroups", S_IRUGO|S_IWUSR, proc_setgroups_operations),
> #endif
> };
>
> diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
> index 8d493083486a..feb0f4ec5573 100644
> --- a/include/linux/user_namespace.h
> +++ b/include/linux/user_namespace.h
> @@ -17,6 +17,10 @@ struct uid_gid_map { /* 64 bytes -- 1 cache line */
> } extent[UID_GID_MAP_MAX_EXTENTS];
> };
>
> +#define USERNS_SETGROUPS_ALLOWED 1UL
> +
> +#define USERNS_INIT_FLAGS USERNS_SETGROUPS_ALLOWED
> +
> struct user_namespace {
> struct uid_gid_map uid_map;
> struct uid_gid_map gid_map;
> @@ -27,6 +31,7 @@ struct user_namespace {
> kuid_t owner;
> kgid_t group;
> unsigned int proc_inum;
> + unsigned long flags;
>
> /* Register of per-UID persistent keyrings for this namespace */
> #ifdef CONFIG_PERSISTENT_KEYRINGS
> @@ -60,9 +65,11 @@ struct seq_operations;
> extern const struct seq_operations proc_uid_seq_operations;
> extern const struct seq_operations proc_gid_seq_operations;
> extern const struct seq_operations proc_projid_seq_operations;
> +extern const struct seq_operations proc_setgroups_seq_operations;
> extern ssize_t proc_uid_map_write(struct file *, const char __user *, size_t, loff_t *);
> extern ssize_t proc_gid_map_write(struct file *, const char __user *, size_t, loff_t *);
> extern ssize_t proc_projid_map_write(struct file *, const char __user *, size_t, loff_t *);
> +extern ssize_t proc_setgroups_write(struct file *, const char __user *, size_t, loff_t *);
> extern bool userns_may_setgroups(const struct user_namespace *ns);
> #else
>
> diff --git a/kernel/user.c b/kernel/user.c
> index 4efa39350e44..2d09940c9632 100644
> --- a/kernel/user.c
> +++ b/kernel/user.c
> @@ -51,6 +51,7 @@ struct user_namespace init_user_ns = {
> .owner = GLOBAL_ROOT_UID,
> .group = GLOBAL_ROOT_GID,
> .proc_inum = PROC_USER_INIT_INO,
> + .flags = USERNS_INIT_FLAGS,
> #ifdef CONFIG_PERSISTENT_KEYRINGS
> .persistent_keyring_register_sem =
> __RWSEM_INITIALIZER(init_user_ns.persistent_keyring_register_sem),
> diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
> index 44a555ac6104..b507f9af7ff2 100644
> --- a/kernel/user_namespace.c
> +++ b/kernel/user_namespace.c
> @@ -100,6 +100,11 @@ int create_user_ns(struct cred *new)
> ns->owner = owner;
> ns->group = group;
>
> + /* Inherit USERNS_SETGROUPS_ALLOWED from our parent */
> + mutex_lock(&userns_state_mutex);
> + ns->flags = parent_ns->flags;
> + mutex_unlock(&userns_state_mutex);
> +
> set_cred_user_ns(new, ns);
>
> #ifdef CONFIG_PERSISTENT_KEYRINGS
> @@ -839,6 +844,102 @@ static bool new_idmap_permitted(const struct file *file,
> return false;
> }
>
> +static void *setgroups_m_start(struct seq_file *seq, loff_t *ppos)
> +{
> + struct user_namespace *ns = seq->private;
> +
> + return (*ppos == 0) ? ns : NULL;
> +}
> +
> +static void *setgroups_m_next(struct seq_file *seq, void *v, loff_t *ppos)
> +{
> + ++*ppos;
> + return NULL;
> +}
> +
> +static void setgroups_m_stop(struct seq_file *seq, void *v)
> +{
> +}
> +
> +static int setgroups_m_show(struct seq_file *seq, void *v)
> +{
> + struct user_namespace *ns = seq->private;
> +
> + seq_printf(seq, "%s\n",
> + test_bit(USERNS_SETGROUPS_ALLOWED, &ns->flags) ?
> + "allow" : "deny");
> + return 0;
> +}
> +
> +const struct seq_operations proc_setgroups_seq_operations = {
> + .start = setgroups_m_start,
> + .stop = setgroups_m_stop,
> + .next = setgroups_m_next,
> + .show = setgroups_m_show,
> +};
> +
> +ssize_t proc_setgroups_write(struct file *file, const char __user *buf,
> + size_t count, loff_t *ppos)
> +{
> + struct seq_file *seq = file->private_data;
> + struct user_namespace *ns = seq->private;
> + char kbuf[8], *pos;
> + bool setgroups_allowed;
> + ssize_t ret;
> +
> + ret = -EACCES;
> + if (!file_ns_capable(file, ns, CAP_SYS_ADMIN))
> + goto out;
> +
> + /* Only allow a very narrow range of strings to be written */
> + ret = -EINVAL;
> + if ((*ppos != 0) || (count >= sizeof(kbuf)))
> + goto out;
> +
> + /* What was written? */
> + ret = -EFAULT;
> + if (copy_from_user(kbuf, buf, count))
> + goto out;
> + kbuf[count] = '\0';
> + pos = kbuf;
> +
> + /* What is being requested? */
> + ret = -EINVAL;
> + if (strncmp(pos, "allow", 5) == 0) {
> + pos += 5;
> + setgroups_allowed = true;
> + }
> + else if (strncmp(pos, "deny", 4) == 0) {
> + pos += 4;
> + setgroups_allowed = false;
> + }
> + else
> + goto out;
> +
> + /* Verify there is not trailing junk on the line */
> + pos = skip_spaces(pos);
> + if (*pos != '\0')
> + goto out;
> +
> + mutex_lock(&userns_state_mutex);
> + if (setgroups_allowed) {
> + ret = -EPERM;
> + if (!(ns->flags & USERNS_SETGROUPS_ALLOWED)) {
> + mutex_unlock(&userns_state_mutex);
> + goto out;
> + }
> + } else {
> + ns->flags &= ~USERNS_SETGROUPS_ALLOWED;
> + }
> + mutex_unlock(&userns_state_mutex);
> +
> + /* Report a successful write */
> + *ppos = count;
> + ret = count;
> +out:
> + return ret;
> +}
> +
> bool userns_may_setgroups(const struct user_namespace *ns)
> {
> bool allowed;
> @@ -848,6 +949,8 @@ bool userns_may_setgroups(const struct user_namespace *ns)
> * the user namespace has been established.
> */
> allowed = ns->gid_map.nr_extents != 0;
> + /* Is setgroups allowed? */
> + allowed = allowed && (ns->flags & USERNS_SETGROUPS_ALLOWED);
> mutex_unlock(&userns_state_mutex);
>
> return allowed;
> --
> 1.9.1
>
--
Andy Lutomirski
AMA Capital Management, LLC
^ permalink raw reply
* RE: selftests: question about git repos containing selftest.
From: Young, David @ 2014-12-09 21:29 UTC (permalink / raw)
To: Shuah Khan
Cc: Greg KH, linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <CAKocOOMNS3tZq3nFg7rTFnPRZwV0U-y4=34Yph+qTYN0kqTuQA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Thanks for clearing this up, very helpful!
-dave
-----Original Message-----
From: Shuah Khan [mailto:shuahkhan@gmail.com]
Sent: Tuesday, December 09, 2014 4:27 PM
To: Young, David
Cc: Greg KH; linux-api@vger.kernel.org; shuahkh@osg.samsung.com; linux-kernel@vger.kernel.org
Subject: Re: selftests: question about git repos containing selftest.
On Tue, Dec 9, 2014 at 2:08 PM, Young, David <dayoung@akamai.com> wrote:
>
>> Do you have specific patches in linux-next that you have questions about?
>
> Mostly I am interested in executing kselftests via something like autotest or Hudson/jenkins as a quick smoketest. I understand it's still very much an in-progress feature, but would like the closest thing to a stable set of tests to regularly clone and use. I suppose I could just wait for whatever makes it into mainline, but I'm interested in seeing the planned test coverage and test output so that I can write appropriate "glue" for use with a continuous-integration test system.
>
David,
Please follow fixes branch for patches that are going to be in the next mainline release. I am planning to create devel or experimental branch to make my next revision install target patches available for early testing for people that want to play with work in progress. Hope this is helpful.
thanks,
-- Shuah
^ permalink raw reply
* Re: selftests: question about git repos containing selftest.
From: Shuah Khan @ 2014-12-09 21:27 UTC (permalink / raw)
To: Young, David
Cc: Greg KH, linux-api@vger.kernel.org, shuahkh@osg.samsung.com,
linux-kernel@vger.kernel.org
In-Reply-To: <7F8EB1E5A1A71643ACAD0928E03FFDE90E3D796C56@USMBX1.msg.corp.akamai.com>
On Tue, Dec 9, 2014 at 2:08 PM, Young, David <dayoung@akamai.com> wrote:
>
>> Do you have specific patches in linux-next that you have questions about?
>
> Mostly I am interested in executing kselftests via something like autotest or Hudson/jenkins as a quick smoketest. I understand it's still very much an in-progress feature, but would like the closest thing to a stable set of tests to regularly clone and use. I suppose I could just wait for whatever makes it into mainline, but I'm interested in seeing the planned test coverage and test output so that I can write appropriate "glue" for use with a continuous-integration test system.
>
David,
Please follow fixes branch for patches that are going to be in the next mainline
release. I am planning to create devel or experimental branch to make my next
revision install target patches available for early testing for people
that want to
play with work in progress. Hope this is helpful.
thanks,
-- Shuah
^ permalink raw reply
* RE: selftests: question about git repos containing selftest.
From: Young, David @ 2014-12-09 21:08 UTC (permalink / raw)
To: Shuah Khan
Cc: Greg KH, linux-api@vger.kernel.org, shuahkh@osg.samsung.com,
linux-kernel@vger.kernel.org
In-Reply-To: <CAKocOOMiaUDaP=PJ7R9dtsg001eP68hNLyryVQV=yLMC92aeyg@mail.gmail.com>
> Do you have specific patches in linux-next that you have questions about?
Mostly I am interested in executing kselftests via something like autotest or Hudson/jenkins as a quick smoketest. I understand it's still very much an in-progress feature, but would like the closest thing to a stable set of tests to regularly clone and use. I suppose I could just wait for whatever makes it into mainline, but I'm interested in seeing the planned test coverage and test output so that I can write appropriate "glue" for use with a continuous-integration test system.
-dave
^ permalink raw reply
* Re: selftests: question about git repos containing selftest.
From: Davidlohr Bueso @ 2014-12-09 20:53 UTC (permalink / raw)
To: Shuah Khan
Cc: Young, David, Greg KH, linux-api@vger.kernel.org,
shuahkh@osg.samsung.com, linux-kernel@vger.kernel.org
In-Reply-To: <CAKocOOMiaUDaP=PJ7R9dtsg001eP68hNLyryVQV=yLMC92aeyg@mail.gmail.com>
On Tue, 2014-12-09 at 13:34 -0700, Shuah Khan wrote:
> On Tue, Dec 9, 2014 at 1:25 PM, Young, David <dayoung@akamai.com> wrote:
> > Thanks, I was definitely looking at the master branch of linux-kselftest.
> >
> > There are still more changes in linux-next repo, should those be considered as "in progress"?
> >
>
> Patches in linux-kselftest fixes branch are the ones I included in my
> pull request
> I just sent out. linux-next might have some selftest patches that are part of a
> series that depend on a sub-system API. Maybe that is what you are seeing
> in linux-next.
Is there any reason why Andrew isn't handling kselftests? Considering it
spans multiple subsystems, it seems far more appropriate that way.
^ permalink raw reply
* Re: [PATCH v6] media: platform: add VPFE capture driver support for AM437X
From: Hans Verkuil @ 2014-12-09 20:49 UTC (permalink / raw)
To: Lad, Prabhakar, LMML, devicetree, linux-api; +Cc: LKML, Hans Verkuil
In-Reply-To: <1418154224-6045-1-git-send-email-prabhakar.csengg@gmail.com>
On 12/09/2014 08:43 PM, Lad, Prabhakar wrote:
> From: Benoit Parrot <bparrot@ti.com>
>
> This patch adds Video Processing Front End (VPFE) driver for
> AM437X family of devices
> Driver supports the following:
> - V4L2 API using MMAP buffer access based on videobuf2 api
> - Asynchronous sensor/decoder sub device registration
> - DT support
>
> Signed-off-by: Benoit Parrot <bparrot@ti.com>
> Signed-off-by: Darren Etheridge <detheridge@ti.com>
> Signed-off-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
> ---
> Changes for v6:
> 1: Fixed review comments pointed Hans, fixing race condition.
>
> v5: https://patchwork.kernel.org/patch/5459311/
> v4: https://patchwork.kernel.org/patch/5449211/
> v3: https://patchwork.kernel.org/patch/5434291/
> v2: https://patchwork.kernel.org/patch/5425631/
> v1: https://patchwork.kernel.org/patch/5362661/
>
> .../devicetree/bindings/media/ti-am437x-vpfe.txt | 61 +
> MAINTAINERS | 9 +
> drivers/media/platform/Kconfig | 1 +
> drivers/media/platform/Makefile | 2 +
> drivers/media/platform/am437x/Kconfig | 11 +
> drivers/media/platform/am437x/Makefile | 3 +
> drivers/media/platform/am437x/am437x-vpfe.c | 2777 ++++++++++++++++++++
> drivers/media/platform/am437x/am437x-vpfe.h | 283 ++
> drivers/media/platform/am437x/am437x-vpfe_regs.h | 140 +
> include/uapi/linux/Kbuild | 1 +
> include/uapi/linux/am437x-vpfe.h | 122 +
> 11 files changed, 3410 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/media/ti-am437x-vpfe.txt
> create mode 100644 drivers/media/platform/am437x/Kconfig
> create mode 100644 drivers/media/platform/am437x/Makefile
> create mode 100644 drivers/media/platform/am437x/am437x-vpfe.c
> create mode 100644 drivers/media/platform/am437x/am437x-vpfe.h
> create mode 100644 drivers/media/platform/am437x/am437x-vpfe_regs.h
> create mode 100644 include/uapi/linux/am437x-vpfe.h
>
<snip>
> +/*
> + * vpfe_release : This function is based on the vb2_fop_release
> + * helper function.
> + * It has been augmented to handle module power management,
> + * by disabling/enabling h/w module fcntl clock when necessary.
> + */
> +static int vpfe_release(struct file *file)
> +{
> + struct vpfe_device *vpfe = video_drvdata(file);
> + int ret;
> +
> + mutex_lock(&vpfe->lock);
> +
> + ret = _vb2_fop_release(file, NULL);
> + if (v4l2_fh_is_singular_file(file))
> + vpfe_ccdc_close(&vpfe->ccdc, vpfe->pdev);
This function seems cursed since your _vb2_fop_release call should
go *after* the v4l2_fh_is_singular_file() check.
I've fixed that in the patch in my pull request, so there is no need
for a v7. I know you've tested that since that was the order in your v5
version of this patch.
Regards,
Hans
> +
> + mutex_unlock(&vpfe->lock);
> +
> + return ret;
> +}
> +
> +/*
> + * vpfe_open : This function is based on the v4l2_fh_open helper function.
> + * It has been augmented to handle module power management,
> + * by disabling/enabling h/w module fcntl clock when necessary.
> + */
> +static int vpfe_open(struct file *file)
> +{
> + struct vpfe_device *vpfe = video_drvdata(file);
> + int ret;
> +
> + mutex_lock(&vpfe->lock);
> +
> + ret = v4l2_fh_open(file);
> + if (ret) {
> + vpfe_err(vpfe, "v4l2_fh_open failed\n");
> + goto unlock;
> + }
> +
> + if (!v4l2_fh_is_singular_file(file))
> + goto unlock;
> +
> + if (vpfe_initialize_device(vpfe)) {
> + v4l2_fh_release(file);
> + ret = -ENODEV;
> + }
> +
> +unlock:
> + mutex_unlock(&vpfe->lock);
> + return ret;
> +}
^ permalink raw reply
* [CFT][PATCH 8/8] userns: Allow setting gid_maps without privilege when setgroups is disabled
From: Eric W. Biederman @ 2014-12-09 20:43 UTC (permalink / raw)
To: Andy Lutomirski
Cc: linux-man, Kees Cook, Linux API, Linux Containers, Josh Triplett,
stable, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Kenton Varda, LSM, Michael Kerrisk-manpages, Richard Weinberger,
Casey Schaufler, Andrew Morton
In-Reply-To: <87iohklfvj.fsf_-_-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
Now that setgroups can be disabled and not reenabled, setting gid_map
without privielge can now be enabled when setgroups is disabled.
This restores most of the functionality that was lost when unprivileged
setting of gid_map was removed. Applications that use this functionality
will need to check to see if they use setgroups or init_groups, and if they
don't they can be fixed by simply disabling setgroups before writing to
gid_map.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Reviewed-by: Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
kernel/user_namespace.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index b507f9af7ff2..3b29b9a52332 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -826,6 +826,11 @@ static bool new_idmap_permitted(const struct file *file,
kuid_t uid = make_kuid(ns->parent, id);
if (uid_eq(uid, cred->euid))
return true;
+ } else if (cap_setid == CAP_SETGID) {
+ kgid_t gid = make_kgid(ns->parent, id);
+ if (!(ns->flags & USERNS_SETGROUPS_ALLOWED) &&
+ gid_eq(gid, cred->egid))
+ return true;
}
}
--
1.9.1
^ permalink raw reply related
* [CFT][PATCH 7/8] userns: Add a knob to disable setgroups on a per user namespace basis
From: Eric W. Biederman @ 2014-12-09 20:42 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Linux Containers, Josh Triplett, Andrew Morton, Kees Cook,
Michael Kerrisk-manpages, Linux API, linux-man,
linux-kernel@vger.kernel.org, LSM, Casey Schaufler,
Serge E. Hallyn, Richard Weinberger, Kenton Varda, stable
In-Reply-To: <87iohklfvj.fsf_-_-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
- Expose the knob to user space through a proc file /proc/<pid>/setgroups
A value of "deny" means the setgroups system call is disabled in the
current processes user namespace and can not be enabled in the
future in this user namespace.
A value of "allow" means the segtoups system call is enabled.
- Descendant user namespaces inherit the value of setgroups from
their parents.
- A proc file is used (instead of a sysctl) as sysctls
currently do not pass in a struct file so file_ns_capable
is unusable.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
fs/proc/base.c | 31 +++++++++----
include/linux/user_namespace.h | 7 +++
kernel/user.c | 1 +
kernel/user_namespace.c | 103 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 134 insertions(+), 8 deletions(-)
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 772efa45a452..4ebed9f01d97 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2386,7 +2386,7 @@ static int proc_tgid_io_accounting(struct seq_file *m, struct pid_namespace *ns,
#endif /* CONFIG_TASK_IO_ACCOUNTING */
#ifdef CONFIG_USER_NS
-static int proc_id_map_open(struct inode *inode, struct file *file,
+static int proc_userns_open(struct inode *inode, struct file *file,
const struct seq_operations *seq_ops)
{
struct user_namespace *ns = NULL;
@@ -2418,7 +2418,7 @@ err:
return ret;
}
-static int proc_id_map_release(struct inode *inode, struct file *file)
+static int proc_userns_release(struct inode *inode, struct file *file)
{
struct seq_file *seq = file->private_data;
struct user_namespace *ns = seq->private;
@@ -2428,17 +2428,17 @@ static int proc_id_map_release(struct inode *inode, struct file *file)
static int proc_uid_map_open(struct inode *inode, struct file *file)
{
- return proc_id_map_open(inode, file, &proc_uid_seq_operations);
+ return proc_userns_open(inode, file, &proc_uid_seq_operations);
}
static int proc_gid_map_open(struct inode *inode, struct file *file)
{
- return proc_id_map_open(inode, file, &proc_gid_seq_operations);
+ return proc_userns_open(inode, file, &proc_gid_seq_operations);
}
static int proc_projid_map_open(struct inode *inode, struct file *file)
{
- return proc_id_map_open(inode, file, &proc_projid_seq_operations);
+ return proc_userns_open(inode, file, &proc_projid_seq_operations);
}
static const struct file_operations proc_uid_map_operations = {
@@ -2446,7 +2446,7 @@ static const struct file_operations proc_uid_map_operations = {
.write = proc_uid_map_write,
.read = seq_read,
.llseek = seq_lseek,
- .release = proc_id_map_release,
+ .release = proc_userns_release,
};
static const struct file_operations proc_gid_map_operations = {
@@ -2454,7 +2454,7 @@ static const struct file_operations proc_gid_map_operations = {
.write = proc_gid_map_write,
.read = seq_read,
.llseek = seq_lseek,
- .release = proc_id_map_release,
+ .release = proc_userns_release,
};
static const struct file_operations proc_projid_map_operations = {
@@ -2462,7 +2462,20 @@ static const struct file_operations proc_projid_map_operations = {
.write = proc_projid_map_write,
.read = seq_read,
.llseek = seq_lseek,
- .release = proc_id_map_release,
+ .release = proc_userns_release,
+};
+
+static int proc_setgroups_open(struct inode *inode, struct file *file)
+{
+ return proc_userns_open(inode, file, &proc_setgroups_seq_operations);
+}
+
+static const struct file_operations proc_setgroups_operations = {
+ .open = proc_setgroups_open,
+ .write = proc_setgroups_write,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = proc_userns_release,
};
#endif /* CONFIG_USER_NS */
@@ -2572,6 +2585,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations),
REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations),
REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
+ REG("setgroups", S_IRUGO|S_IWUSR, proc_setgroups_operations),
#endif
#ifdef CONFIG_CHECKPOINT_RESTORE
REG("timers", S_IRUGO, proc_timers_operations),
@@ -2913,6 +2927,7 @@ static const struct pid_entry tid_base_stuff[] = {
REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations),
REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations),
REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
+ REG("setgroups", S_IRUGO|S_IWUSR, proc_setgroups_operations),
#endif
};
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 8d493083486a..feb0f4ec5573 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -17,6 +17,10 @@ struct uid_gid_map { /* 64 bytes -- 1 cache line */
} extent[UID_GID_MAP_MAX_EXTENTS];
};
+#define USERNS_SETGROUPS_ALLOWED 1UL
+
+#define USERNS_INIT_FLAGS USERNS_SETGROUPS_ALLOWED
+
struct user_namespace {
struct uid_gid_map uid_map;
struct uid_gid_map gid_map;
@@ -27,6 +31,7 @@ struct user_namespace {
kuid_t owner;
kgid_t group;
unsigned int proc_inum;
+ unsigned long flags;
/* Register of per-UID persistent keyrings for this namespace */
#ifdef CONFIG_PERSISTENT_KEYRINGS
@@ -60,9 +65,11 @@ struct seq_operations;
extern const struct seq_operations proc_uid_seq_operations;
extern const struct seq_operations proc_gid_seq_operations;
extern const struct seq_operations proc_projid_seq_operations;
+extern const struct seq_operations proc_setgroups_seq_operations;
extern ssize_t proc_uid_map_write(struct file *, const char __user *, size_t, loff_t *);
extern ssize_t proc_gid_map_write(struct file *, const char __user *, size_t, loff_t *);
extern ssize_t proc_projid_map_write(struct file *, const char __user *, size_t, loff_t *);
+extern ssize_t proc_setgroups_write(struct file *, const char __user *, size_t, loff_t *);
extern bool userns_may_setgroups(const struct user_namespace *ns);
#else
diff --git a/kernel/user.c b/kernel/user.c
index 4efa39350e44..2d09940c9632 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -51,6 +51,7 @@ struct user_namespace init_user_ns = {
.owner = GLOBAL_ROOT_UID,
.group = GLOBAL_ROOT_GID,
.proc_inum = PROC_USER_INIT_INO,
+ .flags = USERNS_INIT_FLAGS,
#ifdef CONFIG_PERSISTENT_KEYRINGS
.persistent_keyring_register_sem =
__RWSEM_INITIALIZER(init_user_ns.persistent_keyring_register_sem),
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 44a555ac6104..b507f9af7ff2 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -100,6 +100,11 @@ int create_user_ns(struct cred *new)
ns->owner = owner;
ns->group = group;
+ /* Inherit USERNS_SETGROUPS_ALLOWED from our parent */
+ mutex_lock(&userns_state_mutex);
+ ns->flags = parent_ns->flags;
+ mutex_unlock(&userns_state_mutex);
+
set_cred_user_ns(new, ns);
#ifdef CONFIG_PERSISTENT_KEYRINGS
@@ -839,6 +844,102 @@ static bool new_idmap_permitted(const struct file *file,
return false;
}
+static void *setgroups_m_start(struct seq_file *seq, loff_t *ppos)
+{
+ struct user_namespace *ns = seq->private;
+
+ return (*ppos == 0) ? ns : NULL;
+}
+
+static void *setgroups_m_next(struct seq_file *seq, void *v, loff_t *ppos)
+{
+ ++*ppos;
+ return NULL;
+}
+
+static void setgroups_m_stop(struct seq_file *seq, void *v)
+{
+}
+
+static int setgroups_m_show(struct seq_file *seq, void *v)
+{
+ struct user_namespace *ns = seq->private;
+
+ seq_printf(seq, "%s\n",
+ test_bit(USERNS_SETGROUPS_ALLOWED, &ns->flags) ?
+ "allow" : "deny");
+ return 0;
+}
+
+const struct seq_operations proc_setgroups_seq_operations = {
+ .start = setgroups_m_start,
+ .stop = setgroups_m_stop,
+ .next = setgroups_m_next,
+ .show = setgroups_m_show,
+};
+
+ssize_t proc_setgroups_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct seq_file *seq = file->private_data;
+ struct user_namespace *ns = seq->private;
+ char kbuf[8], *pos;
+ bool setgroups_allowed;
+ ssize_t ret;
+
+ ret = -EACCES;
+ if (!file_ns_capable(file, ns, CAP_SYS_ADMIN))
+ goto out;
+
+ /* Only allow a very narrow range of strings to be written */
+ ret = -EINVAL;
+ if ((*ppos != 0) || (count >= sizeof(kbuf)))
+ goto out;
+
+ /* What was written? */
+ ret = -EFAULT;
+ if (copy_from_user(kbuf, buf, count))
+ goto out;
+ kbuf[count] = '\0';
+ pos = kbuf;
+
+ /* What is being requested? */
+ ret = -EINVAL;
+ if (strncmp(pos, "allow", 5) == 0) {
+ pos += 5;
+ setgroups_allowed = true;
+ }
+ else if (strncmp(pos, "deny", 4) == 0) {
+ pos += 4;
+ setgroups_allowed = false;
+ }
+ else
+ goto out;
+
+ /* Verify there is not trailing junk on the line */
+ pos = skip_spaces(pos);
+ if (*pos != '\0')
+ goto out;
+
+ mutex_lock(&userns_state_mutex);
+ if (setgroups_allowed) {
+ ret = -EPERM;
+ if (!(ns->flags & USERNS_SETGROUPS_ALLOWED)) {
+ mutex_unlock(&userns_state_mutex);
+ goto out;
+ }
+ } else {
+ ns->flags &= ~USERNS_SETGROUPS_ALLOWED;
+ }
+ mutex_unlock(&userns_state_mutex);
+
+ /* Report a successful write */
+ *ppos = count;
+ ret = count;
+out:
+ return ret;
+}
+
bool userns_may_setgroups(const struct user_namespace *ns)
{
bool allowed;
@@ -848,6 +949,8 @@ bool userns_may_setgroups(const struct user_namespace *ns)
* the user namespace has been established.
*/
allowed = ns->gid_map.nr_extents != 0;
+ /* Is setgroups allowed? */
+ allowed = allowed && (ns->flags & USERNS_SETGROUPS_ALLOWED);
mutex_unlock(&userns_state_mutex);
return allowed;
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [CFT][PATCH 6/8] userns: Rename id_map_mutex to userns_state_mutex
From: Eric W. Biederman @ 2014-12-09 20:41 UTC (permalink / raw)
To: Andy Lutomirski
Cc: linux-man, Kees Cook, Linux API, Linux Containers, Josh Triplett,
stable, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Kenton Varda, LSM, Michael Kerrisk-manpages, Richard Weinberger,
Casey Schaufler, Andrew Morton
In-Reply-To: <87iohklfvj.fsf_-_-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
Generalize id_map_mutex so it can be used for more state of a user namespace.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
kernel/user_namespace.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 1e34de2fbd60..44a555ac6104 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -24,6 +24,7 @@
#include <linux/fs_struct.h>
static struct kmem_cache *user_ns_cachep __read_mostly;
+static DEFINE_MUTEX(userns_state_mutex);
static bool new_idmap_permitted(const struct file *file,
struct user_namespace *ns, int cap_setid,
@@ -583,9 +584,6 @@ static bool mappings_overlap(struct uid_gid_map *new_map,
return false;
}
-
-static DEFINE_MUTEX(id_map_mutex);
-
static ssize_t map_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos,
int cap_setid,
@@ -602,7 +600,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
ssize_t ret = -EINVAL;
/*
- * The id_map_mutex serializes all writes to any given map.
+ * The userns_state_mutex serializes all writes to any given map.
*
* Any map is only ever written once.
*
@@ -620,7 +618,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
* order and smp_rmb() is guaranteed that we don't have crazy
* architectures returning stale data.
*/
- mutex_lock(&id_map_mutex);
+ mutex_lock(&userns_state_mutex);
ret = -EPERM;
/* Only allow one successful write to the map */
@@ -750,7 +748,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
*ppos = count;
ret = count;
out:
- mutex_unlock(&id_map_mutex);
+ mutex_unlock(&userns_state_mutex);
if (page)
free_page(page);
return ret;
@@ -845,12 +843,12 @@ bool userns_may_setgroups(const struct user_namespace *ns)
{
bool allowed;
- mutex_lock(&id_map_mutex);
+ mutex_lock(&userns_state_mutex);
/* It is not safe to use setgroups until a gid mapping in
* the user namespace has been established.
*/
allowed = ns->gid_map.nr_extents != 0;
- mutex_unlock(&id_map_mutex);
+ mutex_unlock(&userns_state_mutex);
return allowed;
}
--
1.9.1
^ permalink raw reply related
* [CFT][PATCH 5/8] userns: Only allow the creator of the userns unprivileged mappings
From: Eric W. Biederman @ 2014-12-09 20:41 UTC (permalink / raw)
To: Andy Lutomirski
Cc: linux-man, Kees Cook, Linux API, Linux Containers, Josh Triplett,
stable, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Kenton Varda, LSM, Michael Kerrisk-manpages, Richard Weinberger,
Casey Schaufler, Andrew Morton
In-Reply-To: <87iohklfvj.fsf_-_-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
If you did not create the user namespace and are allowed
to write to uid_map or gid_map you should already have the necessary
privilege in the parent user namespace to establish any mapping
you want so this will not affect userspace in practice.
Limiting unprivileged uid mapping establishment to the creator of the
user namespace makes it easier to verify all credentials obtained with
the uid mapping can be obtained without the uid mapping without
privilege.
Limiting unprivileged gid mapping establishment (which is temporarily
absent) to the creator of the user namespace also ensures that the
combination of uid and gid can already be obtained without privilege.
This is part of the fix for CVE-2014-8989.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Reviewed-by: Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
kernel/user_namespace.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 9451b12a9b6c..1e34de2fbd60 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -812,14 +812,16 @@ static bool new_idmap_permitted(const struct file *file,
struct user_namespace *ns, int cap_setid,
struct uid_gid_map *new_map)
{
+ const struct cred *cred = file->f_cred;
/* Don't allow mappings that would allow anything that wouldn't
* be allowed without the establishment of unprivileged mappings.
*/
- if ((new_map->nr_extents == 1) && (new_map->extent[0].count == 1)) {
+ if ((new_map->nr_extents == 1) && (new_map->extent[0].count == 1) &&
+ uid_eq(ns->owner, cred->euid)) {
u32 id = new_map->extent[0].lower_first;
if (cap_setid == CAP_SETUID) {
kuid_t uid = make_kuid(ns->parent, id);
- if (uid_eq(uid, file->f_cred->euid))
+ if (uid_eq(uid, cred->euid))
return true;
}
}
--
1.9.1
^ permalink raw reply related
* [CFT][PATCH 4/8] userns: Check euid no fsuid when establishing an unprivileged uid mapping
From: Eric W. Biederman @ 2014-12-09 20:39 UTC (permalink / raw)
To: Andy Lutomirski
Cc: linux-man, Kees Cook, Linux API, Linux Containers, Josh Triplett,
stable, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Kenton Varda, LSM, Michael Kerrisk-manpages, Richard Weinberger,
Casey Schaufler, Andrew Morton
In-Reply-To: <87iohklfvj.fsf_-_-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
setresuid allows the euid to be set to any of uid, euid, suid, and
fsuid. Therefor it is safe to allow an unprivileged user to map
their euid and use CAP_SETUID privileged with exactly that uid,
as no new credentials can be obtained.
I can not find a combination of existing system calls that allows setting
uid, euid, suid, and fsuid from the fsuid making the previous use
of fsuid for allowing unprivileged mappings a bug.
This is part of a fix for CVE-2014-8989.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Reviewed-by: Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
kernel/user_namespace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 1ce6d67c07b7..9451b12a9b6c 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -819,7 +819,7 @@ static bool new_idmap_permitted(const struct file *file,
u32 id = new_map->extent[0].lower_first;
if (cap_setid == CAP_SETUID) {
kuid_t uid = make_kuid(ns->parent, id);
- if (uid_eq(uid, file->f_cred->fsuid))
+ if (uid_eq(uid, file->f_cred->euid))
return true;
}
}
--
1.9.1
^ permalink raw reply related
* [CFT][PATCH 3/8] userns: Don't allow unprivileged creation of gid mappings
From: Eric W. Biederman @ 2014-12-09 20:39 UTC (permalink / raw)
To: Andy Lutomirski
Cc: linux-man, Kees Cook, Linux API, Linux Containers, Josh Triplett,
stable, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Kenton Varda, LSM, Michael Kerrisk-manpages, Richard Weinberger,
Casey Schaufler, Andrew Morton
In-Reply-To: <87iohklfvj.fsf_-_-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
As any gid mapping will allow and must allow for backwards
compatibility dropping groups don't allow any gid mappings to be
established without CAP_SETGID in the parent user namespace.
For a small class of applications this change breaks userspace
and removes useful functionality. This small class of applications
includes tools/testing/selftests/mount/unprivilged-remount-test.c
Most of the removed functionality will be added back with the addition
of a one way knob to disable setgroups. Once setgroups is disabled
setting the gid_map becomes as safe as setting the uid_map.
For more common applications that set the uid_map and the gid_map
with privilege this change will have no affect.
This is part of a fix for CVE-2014-8989.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
kernel/user_namespace.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 27c8dab48c07..1ce6d67c07b7 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -821,10 +821,6 @@ static bool new_idmap_permitted(const struct file *file,
kuid_t uid = make_kuid(ns->parent, id);
if (uid_eq(uid, file->f_cred->fsuid))
return true;
- } else if (cap_setid == CAP_SETGID) {
- kgid_t gid = make_kgid(ns->parent, id);
- if (gid_eq(gid, file->f_cred->fsgid))
- return true;
}
}
--
1.9.1
^ permalink raw reply related
* [CFT][PATCH 2/8] userns: Don't allow setgroups until a gid mapping has been setablished
From: Eric W. Biederman @ 2014-12-09 20:38 UTC (permalink / raw)
To: Andy Lutomirski
Cc: linux-man, Kees Cook, Linux API, Linux Containers, Josh Triplett,
stable, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Kenton Varda, LSM, Michael Kerrisk-manpages, Richard Weinberger,
Casey Schaufler, Andrew Morton
In-Reply-To: <87iohklfvj.fsf_-_-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
setgroups is unique in not needing a valid mapping before it can be called,
in the case of setgroups(0, NULL) which drops all supplemental groups.
The design of the user namespace assumes that CAP_SETGID can not actually
be used until a gid mapping is established. Therefore add a helper function
to see if the user namespace gid mapping has been established and call
that function in the setgroups permission check.
This is part of the fix for CVE-2014-8989, being able to drop groups
without privilege using user namespaces.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
include/linux/user_namespace.h | 5 +++++
kernel/groups.c | 4 +++-
kernel/user_namespace.c | 14 ++++++++++++++
3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index e95372654f09..8d493083486a 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -63,6 +63,7 @@ extern const struct seq_operations proc_projid_seq_operations;
extern ssize_t proc_uid_map_write(struct file *, const char __user *, size_t, loff_t *);
extern ssize_t proc_gid_map_write(struct file *, const char __user *, size_t, loff_t *);
extern ssize_t proc_projid_map_write(struct file *, const char __user *, size_t, loff_t *);
+extern bool userns_may_setgroups(const struct user_namespace *ns);
#else
static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
@@ -87,6 +88,10 @@ static inline void put_user_ns(struct user_namespace *ns)
{
}
+static inline bool userns_may_setgroups(const struct user_namespace *ns)
+{
+ return true;
+}
#endif
#endif /* _LINUX_USER_H */
diff --git a/kernel/groups.c b/kernel/groups.c
index 02d8a251c476..664411f171b5 100644
--- a/kernel/groups.c
+++ b/kernel/groups.c
@@ -6,6 +6,7 @@
#include <linux/slab.h>
#include <linux/security.h>
#include <linux/syscalls.h>
+#include <linux/user_namespace.h>
#include <asm/uaccess.h>
/* init to 2 - one for init_task, one to ensure it is never freed */
@@ -217,7 +218,8 @@ bool may_setgroups(void)
{
struct user_namespace *user_ns = current_user_ns();
- return ns_capable(user_ns, CAP_SETGID);
+ return ns_capable(user_ns, CAP_SETGID) &&
+ userns_may_setgroups(user_ns);
}
/*
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index b99c862a2e3f..27c8dab48c07 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -843,6 +843,20 @@ static bool new_idmap_permitted(const struct file *file,
return false;
}
+bool userns_may_setgroups(const struct user_namespace *ns)
+{
+ bool allowed;
+
+ mutex_lock(&id_map_mutex);
+ /* It is not safe to use setgroups until a gid mapping in
+ * the user namespace has been established.
+ */
+ allowed = ns->gid_map.nr_extents != 0;
+ mutex_unlock(&id_map_mutex);
+
+ return allowed;
+}
+
static void *userns_get(struct task_struct *task)
{
struct user_namespace *user_ns;
--
1.9.1
^ permalink raw reply related
* [PATCH V4] powerpc: add little endian flag to syscall_get_arch()
From: Richard Guy Briggs @ 2014-12-09 20:37 UTC (permalink / raw)
To: linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-api-u79uwXL29TY76Z2rM5mHXA
Cc: Richard Guy Briggs, mpe-Gsx/Oe8HsFggBc27wqDAHg,
anton-eUNUBHrolfbYtjvyW6yDsg, sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
eparis-FjpueFixGhCM4zKIHC2jIg, pmoore-H+wXaHxf7aLQT0dZR+AlfA,
tonyj-l3A5Bk7waGM
Since both ppc and ppc64 have LE variants which are now reported by uname, add
that flag (__AUDIT_ARCH_LE) to syscall_get_arch() and add AUDIT_ARCH_PPC64LE
variant.
Without this, perf trace and auditctl fail.
Mainline kernel reports ppc64le (per a058801) but there is no matching
AUDIT_ARCH_PPC64LE.
Since 32-bit PPC LE is not supported by audit, don't advertise it in
AUDIT_ARCH_PPC* variants.
See:
https://www.redhat.com/archives/linux-audit/2014-August/msg00082.html
https://www.redhat.com/archives/linux-audit/2014-December/msg00004.html
Signed-off-by: Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
arch/powerpc/include/asm/syscall.h | 6 +++++-
include/uapi/linux/audit.h | 2 ++
2 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h
index 6fa2708..d1934e5 100644
--- a/arch/powerpc/include/asm/syscall.h
+++ b/arch/powerpc/include/asm/syscall.h
@@ -90,6 +90,10 @@ static inline void syscall_set_arguments(struct task_struct *task,
static inline int syscall_get_arch(void)
{
- return is_32bit_task() ? AUDIT_ARCH_PPC : AUDIT_ARCH_PPC64;
+ int arch = is_32bit_task() ? AUDIT_ARCH_PPC : AUDIT_ARCH_PPC64;
+#ifdef __LITTLE_ENDIAN__
+ arch |= __AUDIT_ARCH_LE;
+#endif
+ return arch;
}
#endif /* _ASM_SYSCALL_H */
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 4d100c8..d82beec 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -364,7 +364,9 @@ enum {
#define AUDIT_ARCH_PARISC (EM_PARISC)
#define AUDIT_ARCH_PARISC64 (EM_PARISC|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_PPC (EM_PPC)
+/* do not define AUDIT_ARCH_PPCLE since it is not supported by audit */
#define AUDIT_ARCH_PPC64 (EM_PPC64|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_PPC64LE (EM_PPC64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_S390 (EM_S390)
#define AUDIT_ARCH_S390X (EM_S390|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_SH (EM_SH)
--
1.7.1
^ permalink raw reply related
* [CFT][PATCH 1/8] userns: Document what the invariant required for safe unprivileged mappings.
From: Eric W. Biederman @ 2014-12-09 20:36 UTC (permalink / raw)
To: Andy Lutomirski
Cc: linux-man, Kees Cook, Linux API, Linux Containers, Josh Triplett,
stable, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Kenton Varda, LSM, Michael Kerrisk-manpages, Richard Weinberger,
Casey Schaufler, Andrew Morton
In-Reply-To: <87r3w8liw4.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
The rule is simple. Don't allow anything that wouldn't be allowed
without unprivileged mappings.
It was previously overlooked that establishing gid mappings would
allow dropping groups and potentially gaining permission to files and
directories that had lesser permissions for a specific group than for
all other users.
This is the rule needed to fix CVE-2014-8989 and prevent any other
security issues with new_idmap_permitted.
The reason for this rule is that the unix permission model is old and
there are programs out there somewhere that take advantage of every
little corner of it. So allowing a uid or gid mapping to be
established without privielge that would allow anything that would not
be allowed without that mapping will result in expectations from some
code somewhere being violated. Violated expectations about the
behavior of the OS is a long way to say a security issue.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
kernel/user_namespace.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index aa312b0dc3ec..b99c862a2e3f 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -812,7 +812,9 @@ static bool new_idmap_permitted(const struct file *file,
struct user_namespace *ns, int cap_setid,
struct uid_gid_map *new_map)
{
- /* Allow mapping to your own filesystem ids */
+ /* Don't allow mappings that would allow anything that wouldn't
+ * be allowed without the establishment of unprivileged mappings.
+ */
if ((new_map->nr_extents == 1) && (new_map->extent[0].count == 1)) {
u32 id = new_map->extent[0].lower_first;
if (cap_setid == CAP_SETUID) {
--
1.9.1
^ permalink raw reply related
* Re: selftests: question about git repos containing selftest.
From: Shuah Khan @ 2014-12-09 20:34 UTC (permalink / raw)
To: Young, David
Cc: Greg KH, linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <7F8EB1E5A1A71643ACAD0928E03FFDE90E3D796C21-/aPJBeqlRkAyyULh10xnlCahX2Nl78RV0E9HWUfgJXw@public.gmane.org>
On Tue, Dec 9, 2014 at 1:25 PM, Young, David <dayoung-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org> wrote:
> Thanks, I was definitely looking at the master branch of linux-kselftest.
>
> There are still more changes in linux-next repo, should those be considered as "in progress"?
>
Patches in linux-kselftest fixes branch are the ones I included in my
pull request
I just sent out. linux-next might have some selftest patches that are part of a
series that depend on a sub-system API. Maybe that is what you are seeing
in linux-next.
For example there are ftrace selftest patches in linux-next that
depend on ftrace
sub-system, hence they funnel through ftrace. Same thing happens with mm
related things.
Do you have specific patches in linux-next that you have questions about?
-- Shuah
^ permalink raw reply
* RE: selftests: question about git repos containing selftest.
From: Young, David @ 2014-12-09 20:25 UTC (permalink / raw)
To: Shuah Khan, Greg KH
Cc: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <CAKocOOMGoCtDjG24cJhkrJ=EyhbW-qy6=v5pJaRBeSPZuvZWfA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Thanks, I was definitely looking at the master branch of linux-kselftest.
There are still more changes in linux-next repo, should those be considered as "in progress"?
-dave
-----Original Message-----
From: Shuah Khan [mailto:shuahkhan@gmail.com]
Sent: Tuesday, December 09, 2014 3:21 PM
To: Greg KH
Cc: Young, David; linux-api@vger.kernel.org; shuahkh@osg.samsung.com; linux-kernel@vger.kernel.org
Subject: Re: selftests: question about git repos containing selftest.
On Tue, Dec 9, 2014 at 12:46 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
> On Tue, Dec 09, 2014 at 02:22:42PM -0500, Young, David wrote:
>> Greetings,
>>
>> I'm trying out the new kernel selftests and was looking for the "bleeding edge" repository to clone. According to the wiki https://kselftest.wiki.kernel.org/ this is the appropriate repo:
>> git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.g
>> it
>>
>> However, I am finding newer and more frequent changes are in linux-next.
>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
>>
>> Which should I clone for the most fresh changes?
>
> Are you sure you are looking at the correct branch for that git repo?
> Which one were you using?
>
Please find the patches slated for 3.19--rc1 in fixes branch. These are the ones that get pulled into linux-next for integration testing.
-- Shuah
^ permalink raw reply
* Re: selftests: question about git repos containing selftest.
From: Shuah Khan @ 2014-12-09 20:21 UTC (permalink / raw)
To: Greg KH
Cc: Young, David, linux-api@vger.kernel.org, shuahkh@osg.samsung.com,
linux-kernel@vger.kernel.org
In-Reply-To: <20141209194602.GB20166@kroah.com>
On Tue, Dec 9, 2014 at 12:46 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
> On Tue, Dec 09, 2014 at 02:22:42PM -0500, Young, David wrote:
>> Greetings,
>>
>> I'm trying out the new kernel selftests and was looking for the "bleeding edge" repository to clone. According to the wiki https://kselftest.wiki.kernel.org/ this is the appropriate repo:
>> git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git
>>
>> However, I am finding newer and more frequent changes are in linux-next.
>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
>>
>> Which should I clone for the most fresh changes?
>
> Are you sure you are looking at the correct branch for that git repo?
> Which one were you using?
>
Please find the patches slated for 3.19--rc1 in fixes branch. These
are the ones that
get pulled into linux-next for integration testing.
-- Shuah
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox