Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759260AbbBIEC1 (ORCPT ); Sun, 8 Feb 2015 23:02:27 -0500 Received: from e31.co.us.ibm.com ([32.97.110.149]:46591 "EHLO e31.co.us.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751552AbbBIECZ (ORCPT ); Sun, 8 Feb 2015 23:02:25 -0500 Date: Sun, 8 Feb 2015 20:02:17 -0800 From: "Paul E. McKenney" To: Iulia Manda Cc: gnomes@lxorguk.ukuu.org.uk, josh@joshtriplett.org, peterz@infradead.org, mhocko@suse.cz, akpm@linux-foundation.org, linux-kernel@vger.kernel.org, serge.hallyn@canonical.com, dvhart@linux.intel.com, tim.bird@sonymobile.com Subject: Re: [PATCH v3] kernel: Conditionally support non-root users, groups and capabilities Message-ID: <20150209040217.GA23091@linux.vnet.ibm.com> Reply-To: paulmck@linux.vnet.ibm.com References: <20150206000356.GA11758@winterfell> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150206000356.GA11758@winterfell> User-Agent: Mutt/1.5.21 (2010-09-15) X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15020904-8236-0000-0000-00000946DDE5 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 16274 Lines: 487 On Fri, Feb 06, 2015 at 02:03:56AM +0200, Iulia Manda wrote: > There are a lot of embedded systems that run most or all of their functionality > in init, running as root:root. For these systems, supporting multiple users is > not necessary. > > This patch adds a new symbol, CONFIG_MULTIUSER, that makes support for non-root > users, non-root groups, and capabilities optional. It is enabled under > CONFIG_EXPERT menu. > > When this symbol is not defined, UID and GID are zero in any possible case > and processes always have all capabilities. > > The following syscalls are compiled out: setuid, setregid, setgid, > setreuid, setresuid, getresuid, setresgid, getresgid, setgroups, getgroups, > setfsuid, setfsgid, capget, capset. > > Also, groups.c is compiled out completely. > > This change saves about 25 KB on a defconfig build. > > The kernel was booted in Qemu. All the common functionalities work. Adding > users/groups is not possible, failing with -ENOSYS. > > Bloat-o-meter output: > add/remove: 7/87 grow/shrink: 19/397 up/down: 1675/-26325 (-24650) I presume that v4 will have your Signed-off-by. ;-) Testing on my rcutorture setup uncovered an additional required dependency, please see patch at the end of this email. With that fix, either separately or merged into your patch: Tested-by: Paul E. McKenney One question below about moving the definition of capable(). Either way: Reviewed-by: Paul E. McKenney > --- > Changes since v2: > - rename symbol; > - make SECURITY dependent on MULTIUSER > > arch/s390/Kconfig | 1 + > drivers/staging/lustre/lustre/Kconfig | 1 + > fs/nfsd/Kconfig | 1 + > include/linux/capability.h | 29 +++++++++++++++++++++++++++ > include/linux/cred.h | 23 ++++++++++++++++++---- > include/linux/uidgid.h | 12 +++++++++++ > init/Kconfig | 19 +++++++++++++++++- > kernel/Makefile | 4 +++- > kernel/capability.c | 35 ++++++++++++++++++--------------- > kernel/cred.c | 3 +++ > kernel/groups.c | 3 --- > kernel/sys.c | 2 ++ > kernel/sys_ni.c | 14 +++++++++++++ > net/sunrpc/Kconfig | 2 ++ > security/Kconfig | 1 + > 15 files changed, 125 insertions(+), 25 deletions(-) > > diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig > index 68b68d7..71fb2d1 100644 > --- a/arch/s390/Kconfig > +++ b/arch/s390/Kconfig > @@ -324,6 +324,7 @@ config COMPAT > select COMPAT_BINFMT_ELF if BINFMT_ELF > select ARCH_WANT_OLD_COMPAT_IPC > select COMPAT_OLD_SIGACTION > + depends on MULTIUSER > help > Select this option if you want to enable your system kernel to > handle system-calls from ELF binaries for 31 bit ESA. This option > diff --git a/drivers/staging/lustre/lustre/Kconfig b/drivers/staging/lustre/lustre/Kconfig > index 6725467..62c7bba 100644 > --- a/drivers/staging/lustre/lustre/Kconfig > +++ b/drivers/staging/lustre/lustre/Kconfig > @@ -10,6 +10,7 @@ config LUSTRE_FS > select CRYPTO_SHA1 > select CRYPTO_SHA256 > select CRYPTO_SHA512 > + depends on MULTIUSER > help > This option enables Lustre file system client support. Choose Y > here if you want to access a Lustre file system cluster. To compile > diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig > index 7339515..df0a5d9 100644 > --- a/fs/nfsd/Kconfig > +++ b/fs/nfsd/Kconfig > @@ -6,6 +6,7 @@ config NFSD > select SUNRPC > select EXPORTFS > select NFS_ACL_SUPPORT if NFSD_V2_ACL > + depends on MULTIUSER > help > Choose Y here if you want to allow other computers to access > files residing on this system using Sun's Network File System > diff --git a/include/linux/capability.h b/include/linux/capability.h > index aa93e5e..0c0ae0d 100644 > --- a/include/linux/capability.h > +++ b/include/linux/capability.h > @@ -205,6 +205,7 @@ static inline kernel_cap_t cap_raise_nfsd_set(const kernel_cap_t a, > cap_intersect(permitted, __cap_nfsd_set)); > } > > +#ifdef CONFIG_MULTIUSER > extern bool has_capability(struct task_struct *t, int cap); > extern bool has_ns_capability(struct task_struct *t, > struct user_namespace *ns, int cap); > @@ -213,6 +214,34 @@ extern bool has_ns_capability_noaudit(struct task_struct *t, > struct user_namespace *ns, int cap); > extern bool capable(int cap); > extern bool ns_capable(struct user_namespace *ns, int cap); > +#else > +static inline bool has_capability(struct task_struct *t, int cap) > +{ > + return true; > +} > +static inline bool has_ns_capability(struct task_struct *t, > + struct user_namespace *ns, int cap) > +{ > + return true; > +} > +static inline bool has_capability_noaudit(struct task_struct *t, int cap) > +{ > + return true; > +} > +static inline bool has_ns_capability_noaudit(struct task_struct *t, > + struct user_namespace *ns, int cap) > +{ > + return true; > +} > +static inline bool capable(int cap) > +{ > + return true; > +} > +static inline bool ns_capable(struct user_namespace *ns, int cap) > +{ > + return true; > +} > +#endif /* CONFIG_MULTIUSER */ > extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap); > extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap); > > diff --git a/include/linux/cred.h b/include/linux/cred.h > index 2fb2ca2..8b6c083 100644 > --- a/include/linux/cred.h > +++ b/include/linux/cred.h > @@ -62,9 +62,27 @@ do { \ > groups_free(group_info); \ > } while (0) > > -extern struct group_info *groups_alloc(int); > extern struct group_info init_groups; > +#ifdef CONFIG_MULTIUSER > +extern struct group_info *groups_alloc(int); > extern void groups_free(struct group_info *); > + > +extern int in_group_p(kgid_t); > +extern int in_egroup_p(kgid_t); > +#else > +static inline void groups_free(struct group_info *group_info) > +{ > +} > + > +static inline int in_group_p(kgid_t grp) > +{ > + return 1; > +} > +static inline int in_egroup_p(kgid_t grp) > +{ > + return 1; > +} > +#endif > extern int set_current_groups(struct group_info *); > extern void set_groups(struct cred *, struct group_info *); > extern int groups_search(const struct group_info *, kgid_t); > @@ -74,9 +92,6 @@ extern bool may_setgroups(void); > #define GROUP_AT(gi, i) \ > ((gi)->blocks[(i) / NGROUPS_PER_BLOCK][(i) % NGROUPS_PER_BLOCK]) > > -extern int in_group_p(kgid_t); > -extern int in_egroup_p(kgid_t); > - > /* > * The security context of a task > * > diff --git a/include/linux/uidgid.h b/include/linux/uidgid.h > index 2d1f9b6..0ee05da 100644 > --- a/include/linux/uidgid.h > +++ b/include/linux/uidgid.h > @@ -29,6 +29,7 @@ typedef struct { > #define KUIDT_INIT(value) (kuid_t){ value } > #define KGIDT_INIT(value) (kgid_t){ value } > > +#ifdef CONFIG_MULTIUSER > static inline uid_t __kuid_val(kuid_t uid) > { > return uid.val; > @@ -38,6 +39,17 @@ static inline gid_t __kgid_val(kgid_t gid) > { > return gid.val; > } > +#else > +static inline uid_t __kuid_val(kuid_t uid) > +{ > + return 0; > +} > + > +static inline gid_t __kgid_val(kgid_t gid) > +{ > + return 0; > +} > +#endif > > #define GLOBAL_ROOT_UID KUIDT_INIT(0) > #define GLOBAL_ROOT_GID KGIDT_INIT(0) > diff --git a/init/Kconfig b/init/Kconfig > index 9afb971..b0332c2 100644 > --- a/init/Kconfig > +++ b/init/Kconfig > @@ -394,6 +394,7 @@ endchoice > > config BSD_PROCESS_ACCT > bool "BSD Process Accounting" > + depends on MULTIUSER > help > If you say Y here, a user level program will be able to instruct the > kernel (via a special system call) to write process accounting > @@ -420,6 +421,7 @@ config BSD_PROCESS_ACCT_V3 > config TASKSTATS > bool "Export task/process statistics through netlink" > depends on NET > + depends on MULTIUSER > default n > help > Export selected statistics for tasks/processes through the > @@ -1140,6 +1142,7 @@ config CHECKPOINT_RESTORE > > menuconfig NAMESPACES > bool "Namespaces support" if EXPERT > + depends on MULTIUSER > default !EXPERT > help > Provides the way to make tasks work with different objects using > @@ -1352,11 +1355,25 @@ menuconfig EXPERT > > config UID16 > bool "Enable 16-bit UID system calls" if EXPERT > - depends on HAVE_UID16 > + depends on HAVE_UID16 && MULTIUSER > default y > help > This enables the legacy 16-bit UID syscall wrappers. > > +config MULTIUSER > + bool "Multiple users, groups and capabilities support" if EXPERT > + default y > + help > + This option enables support for non-root users, groups and > + capabilities. > + > + If you say N here, all processes will run with UID 0, GID 0, and all > + possible capabilities. Saying N here also compiles out support for > + system calls related to UIDs, GIDs, and capabilities, such as setuid, > + setgid, and capset. > + > + If unsure, say Y here. > + > config SGETMASK_SYSCALL > bool "sgetmask/ssetmask syscalls support" if EXPERT > def_bool PARISC || MN10300 || BLACKFIN || M68K || PPC || MIPS || X86 || SPARC || CRIS || MICROBLAZE || SUPERH > diff --git a/kernel/Makefile b/kernel/Makefile > index a59481a..554d34e 100644 > --- a/kernel/Makefile > +++ b/kernel/Makefile > @@ -9,7 +9,9 @@ obj-y = fork.o exec_domain.o panic.o \ > extable.o params.o \ > kthread.o sys_ni.o nsproxy.o \ > notifier.o ksysfs.o cred.o reboot.o \ > - async.o range.o groups.o smpboot.o > + async.o range.o smpboot.o > + > +obj-$(CONFIG_MULTIUSER) += groups.o > > ifdef CONFIG_FUNCTION_TRACER > # Do not trace debug files and internal ftrace files > diff --git a/kernel/capability.c b/kernel/capability.c > index 989f5bf..638b0b3 100644 > --- a/kernel/capability.c > +++ b/kernel/capability.c > @@ -35,6 +35,7 @@ static int __init file_caps_disable(char *str) > } > __setup("no_file_caps", file_caps_disable); > > +#ifdef CONFIG_MULTIUSER > /* > * More recent versions of libcap are available from: > * > @@ -386,6 +387,24 @@ bool ns_capable(struct user_namespace *ns, int cap) > } > EXPORT_SYMBOL(ns_capable); > > + > +/** > + * capable - Determine if the current task has a superior capability in effect > + * @cap: The capability to be tested for > + * > + * Return true if the current task has the given superior capability currently > + * available for use, false if not. > + * > + * This sets PF_SUPERPRIV on the task if the capability is available on the > + * assumption that it's about to be used. > + */ > +bool capable(int cap) > +{ > + return ns_capable(&init_user_ns, cap); > +} > +EXPORT_SYMBOL(capable); > +#endif /* CONFIG_MULTIUSER */ > + > /** > * file_ns_capable - Determine if the file's opener had a capability in effect > * @file: The file we want to check > @@ -412,22 +431,6 @@ bool file_ns_capable(const struct file *file, struct user_namespace *ns, > EXPORT_SYMBOL(file_ns_capable); > > /** > - * capable - Determine if the current task has a superior capability in effect > - * @cap: The capability to be tested for > - * > - * Return true if the current task has the given superior capability currently > - * available for use, false if not. > - * > - * This sets PF_SUPERPRIV on the task if the capability is available on the > - * assumption that it's about to be used. > - */ > -bool capable(int cap) > -{ > - return ns_capable(&init_user_ns, cap); > -} > -EXPORT_SYMBOL(capable); > - > -/** OK, I'll bite... Why are we moving capable()? > * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped > * @inode: The inode in question > * @cap: The capability in question > diff --git a/kernel/cred.c b/kernel/cred.c > index e0573a4..ec1c076 100644 > --- a/kernel/cred.c > +++ b/kernel/cred.c > @@ -29,6 +29,9 @@ > > static struct kmem_cache *cred_jar; > > +/* init to 2 - one for init_task, one to ensure it is never freed */ > +struct group_info init_groups = { .usage = ATOMIC_INIT(2) }; > + > /* > * The initial credentials for the initial task > */ > diff --git a/kernel/groups.c b/kernel/groups.c > index 664411f..74d431d 100644 > --- a/kernel/groups.c > +++ b/kernel/groups.c > @@ -9,9 +9,6 @@ > #include > #include > > -/* init to 2 - one for init_task, one to ensure it is never freed */ > -struct group_info init_groups = { .usage = ATOMIC_INIT(2) }; > - > struct group_info *groups_alloc(int gidsetsize) > { > struct group_info *group_info; > diff --git a/kernel/sys.c b/kernel/sys.c > index ea9c881..3094e0f 100644 > --- a/kernel/sys.c > +++ b/kernel/sys.c > @@ -319,6 +319,7 @@ out_unlock: > * SMP: There are not races, the GIDs are checked only by filesystem > * operations (as far as semantic preservation is concerned). > */ > +#ifdef CONFIG_MULTIUSER > SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid) > { > struct user_namespace *ns = current_user_ns(); > @@ -809,6 +810,7 @@ change_okay: > commit_creds(new); > return old_fsgid; > } > +#endif /* CONFIG_MULTIUSER */ > > /** > * sys_getpid - return the thread group id of the current process > diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c > index 5adcb0a..7995ef5 100644 > --- a/kernel/sys_ni.c > +++ b/kernel/sys_ni.c > @@ -159,6 +159,20 @@ cond_syscall(sys_uselib); > cond_syscall(sys_fadvise64); > cond_syscall(sys_fadvise64_64); > cond_syscall(sys_madvise); > +cond_syscall(sys_setuid); > +cond_syscall(sys_setregid); > +cond_syscall(sys_setgid); > +cond_syscall(sys_setreuid); > +cond_syscall(sys_setresuid); > +cond_syscall(sys_getresuid); > +cond_syscall(sys_setresgid); > +cond_syscall(sys_getresgid); > +cond_syscall(sys_setgroups); > +cond_syscall(sys_getgroups); > +cond_syscall(sys_setfsuid); > +cond_syscall(sys_setfsgid); > +cond_syscall(sys_capget); > +cond_syscall(sys_capset); > > /* arch-specific weak syscall entries */ > cond_syscall(sys_pciconfig_read); > diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig > index fb78117..9068e72 100644 > --- a/net/sunrpc/Kconfig > +++ b/net/sunrpc/Kconfig > @@ -1,9 +1,11 @@ > config SUNRPC > tristate > + depends on MULTIUSER > > config SUNRPC_GSS > tristate > select OID_REGISTRY > + depends on MULTIUSER > > config SUNRPC_BACKCHANNEL > bool > diff --git a/security/Kconfig b/security/Kconfig > index beb86b5..bf4ec46 100644 > --- a/security/Kconfig > +++ b/security/Kconfig > @@ -21,6 +21,7 @@ config SECURITY_DMESG_RESTRICT > config SECURITY > bool "Enable different security models" > depends on SYSFS > + depends on MULTIUSER > help > This allows you to choose different security modules to be > configured into your kernel. > -- > 1.7.10.4 ------------------------------------------------------------------------ nfs: Make NFS_FS depend on MULTIUSER Building with CONFIG_MULTIUSER=n results in the following Kconfig warnings: warning: (NFS_FS) selects SUNRPC which has unmet direct dependencies (NETWORK_FILESYSTEMS && MULTIUSER) warning: (NFS_V4 && NFSD_V4 && RPCSEC_GSS_KRB5) selects SUNRPC_GSS which has unmet direct dependencies (NETWORK_FILESYSTEMS && MULTIUSER) warning: (NFS_FS) selects SUNRPC which has unmet direct dependencies (NETWORK_FILESYSTEMS && MULTIUSER) warning: (NFS_V4 && NFSD_V4 && RPCSEC_GSS_KRB5) selects SUNRPC_GSS which has unmet direct dependencies (NETWORK_FILESYSTEMS && MULTIUSER) This patch makes NFS_FS depend on MULTIUSER, eliminating these warnings. Signed-off-by: Paul E. McKenney diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index 3dece03..07a902d 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig @@ -1,6 +1,6 @@ config NFS_FS tristate "NFS client support" - depends on INET && FILE_LOCKING + depends on INET && FILE_LOCKING && MULTIUSER select LOCKD select SUNRPC select NFS_ACL_SUPPORT if NFS_V3_ACL -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/