Skip to content

Commit 2813893

Browse files
dotmndtorvalds
authored andcommitted
kernel: conditionally support non-root users, groups and capabilities
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. In kernel/capability.c, capable function was moved in order to avoid adding two ifdef blocks. This change saves about 25 KB on a defconfig build. The most minimal kernels have total text sizes in the high hundreds of kB rather than low MB. (The 25k goes down a bit with allnoconfig, but not that much. 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) [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Iulia Manda <iulia.manda21@gmail.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent c79574a commit 2813893

16 files changed

Lines changed: 126 additions & 26 deletions

File tree

arch/s390/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ config COMPAT
328328
select COMPAT_BINFMT_ELF if BINFMT_ELF
329329
select ARCH_WANT_OLD_COMPAT_IPC
330330
select COMPAT_OLD_SIGACTION
331+
depends on MULTIUSER
331332
help
332333
Select this option if you want to enable your system kernel to
333334
handle system-calls from ELF binaries for 31 bit ESA. This option

drivers/staging/lustre/lustre/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ config LUSTRE_FS
1010
select CRYPTO_SHA1
1111
select CRYPTO_SHA256
1212
select CRYPTO_SHA512
13+
depends on MULTIUSER
1314
help
1415
This option enables Lustre file system client support. Choose Y
1516
here if you want to access a Lustre file system cluster. To compile

fs/nfs/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
config NFS_FS
22
tristate "NFS client support"
3-
depends on INET && FILE_LOCKING
3+
depends on INET && FILE_LOCKING && MULTIUSER
44
select LOCKD
55
select SUNRPC
66
select NFS_ACL_SUPPORT if NFS_V3_ACL

fs/nfsd/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ config NFSD
66
select SUNRPC
77
select EXPORTFS
88
select NFS_ACL_SUPPORT if NFSD_V2_ACL
9+
depends on MULTIUSER
910
help
1011
Choose Y here if you want to allow other computers to access
1112
files residing on this system using Sun's Network File System

include/linux/capability.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ static inline kernel_cap_t cap_raise_nfsd_set(const kernel_cap_t a,
205205
cap_intersect(permitted, __cap_nfsd_set));
206206
}
207207

208+
#ifdef CONFIG_MULTIUSER
208209
extern bool has_capability(struct task_struct *t, int cap);
209210
extern bool has_ns_capability(struct task_struct *t,
210211
struct user_namespace *ns, int cap);
@@ -213,6 +214,34 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
213214
struct user_namespace *ns, int cap);
214215
extern bool capable(int cap);
215216
extern bool ns_capable(struct user_namespace *ns, int cap);
217+
#else
218+
static inline bool has_capability(struct task_struct *t, int cap)
219+
{
220+
return true;
221+
}
222+
static inline bool has_ns_capability(struct task_struct *t,
223+
struct user_namespace *ns, int cap)
224+
{
225+
return true;
226+
}
227+
static inline bool has_capability_noaudit(struct task_struct *t, int cap)
228+
{
229+
return true;
230+
}
231+
static inline bool has_ns_capability_noaudit(struct task_struct *t,
232+
struct user_namespace *ns, int cap)
233+
{
234+
return true;
235+
}
236+
static inline bool capable(int cap)
237+
{
238+
return true;
239+
}
240+
static inline bool ns_capable(struct user_namespace *ns, int cap)
241+
{
242+
return true;
243+
}
244+
#endif /* CONFIG_MULTIUSER */
216245
extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
217246
extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
218247

include/linux/cred.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,27 @@ do { \
6262
groups_free(group_info); \
6363
} while (0)
6464

65-
extern struct group_info *groups_alloc(int);
6665
extern struct group_info init_groups;
66+
#ifdef CONFIG_MULTIUSER
67+
extern struct group_info *groups_alloc(int);
6768
extern void groups_free(struct group_info *);
69+
70+
extern int in_group_p(kgid_t);
71+
extern int in_egroup_p(kgid_t);
72+
#else
73+
static inline void groups_free(struct group_info *group_info)
74+
{
75+
}
76+
77+
static inline int in_group_p(kgid_t grp)
78+
{
79+
return 1;
80+
}
81+
static inline int in_egroup_p(kgid_t grp)
82+
{
83+
return 1;
84+
}
85+
#endif
6886
extern int set_current_groups(struct group_info *);
6987
extern void set_groups(struct cred *, struct group_info *);
7088
extern int groups_search(const struct group_info *, kgid_t);
@@ -74,9 +92,6 @@ extern bool may_setgroups(void);
7492
#define GROUP_AT(gi, i) \
7593
((gi)->blocks[(i) / NGROUPS_PER_BLOCK][(i) % NGROUPS_PER_BLOCK])
7694

77-
extern int in_group_p(kgid_t);
78-
extern int in_egroup_p(kgid_t);
79-
8095
/*
8196
* The security context of a task
8297
*

include/linux/uidgid.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ typedef struct {
2929
#define KUIDT_INIT(value) (kuid_t){ value }
3030
#define KGIDT_INIT(value) (kgid_t){ value }
3131

32+
#ifdef CONFIG_MULTIUSER
3233
static inline uid_t __kuid_val(kuid_t uid)
3334
{
3435
return uid.val;
@@ -38,6 +39,17 @@ static inline gid_t __kgid_val(kgid_t gid)
3839
{
3940
return gid.val;
4041
}
42+
#else
43+
static inline uid_t __kuid_val(kuid_t uid)
44+
{
45+
return 0;
46+
}
47+
48+
static inline gid_t __kgid_val(kgid_t gid)
49+
{
50+
return 0;
51+
}
52+
#endif
4153

4254
#define GLOBAL_ROOT_UID KUIDT_INIT(0)
4355
#define GLOBAL_ROOT_GID KGIDT_INIT(0)

init/Kconfig

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ endchoice
394394

395395
config BSD_PROCESS_ACCT
396396
bool "BSD Process Accounting"
397+
depends on MULTIUSER
397398
help
398399
If you say Y here, a user level program will be able to instruct the
399400
kernel (via a special system call) to write process accounting
@@ -420,6 +421,7 @@ config BSD_PROCESS_ACCT_V3
420421
config TASKSTATS
421422
bool "Export task/process statistics through netlink"
422423
depends on NET
424+
depends on MULTIUSER
423425
default n
424426
help
425427
Export selected statistics for tasks/processes through the
@@ -1160,6 +1162,7 @@ config CHECKPOINT_RESTORE
11601162

11611163
menuconfig NAMESPACES
11621164
bool "Namespaces support" if EXPERT
1165+
depends on MULTIUSER
11631166
default !EXPERT
11641167
help
11651168
Provides the way to make tasks work with different objects using
@@ -1356,11 +1359,25 @@ menuconfig EXPERT
13561359

13571360
config UID16
13581361
bool "Enable 16-bit UID system calls" if EXPERT
1359-
depends on HAVE_UID16
1362+
depends on HAVE_UID16 && MULTIUSER
13601363
default y
13611364
help
13621365
This enables the legacy 16-bit UID syscall wrappers.
13631366

1367+
config MULTIUSER
1368+
bool "Multiple users, groups and capabilities support" if EXPERT
1369+
default y
1370+
help
1371+
This option enables support for non-root users, groups and
1372+
capabilities.
1373+
1374+
If you say N here, all processes will run with UID 0, GID 0, and all
1375+
possible capabilities. Saying N here also compiles out support for
1376+
system calls related to UIDs, GIDs, and capabilities, such as setuid,
1377+
setgid, and capset.
1378+
1379+
If unsure, say Y here.
1380+
13641381
config SGETMASK_SYSCALL
13651382
bool "sgetmask/ssetmask syscalls support" if EXPERT
13661383
def_bool PARISC || MN10300 || BLACKFIN || M68K || PPC || MIPS || X86 || SPARC || CRIS || MICROBLAZE || SUPERH

kernel/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ obj-y = fork.o exec_domain.o panic.o \
99
extable.o params.o \
1010
kthread.o sys_ni.o nsproxy.o \
1111
notifier.o ksysfs.o cred.o reboot.o \
12-
async.o range.o groups.o smpboot.o
12+
async.o range.o smpboot.o
13+
14+
obj-$(CONFIG_MULTIUSER) += groups.o
1315

1416
ifdef CONFIG_FUNCTION_TRACER
1517
# Do not trace debug files and internal ftrace files

kernel/capability.c

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ static int __init file_caps_disable(char *str)
3535
}
3636
__setup("no_file_caps", file_caps_disable);
3737

38+
#ifdef CONFIG_MULTIUSER
3839
/*
3940
* More recent versions of libcap are available from:
4041
*
@@ -386,6 +387,24 @@ bool ns_capable(struct user_namespace *ns, int cap)
386387
}
387388
EXPORT_SYMBOL(ns_capable);
388389

390+
391+
/**
392+
* capable - Determine if the current task has a superior capability in effect
393+
* @cap: The capability to be tested for
394+
*
395+
* Return true if the current task has the given superior capability currently
396+
* available for use, false if not.
397+
*
398+
* This sets PF_SUPERPRIV on the task if the capability is available on the
399+
* assumption that it's about to be used.
400+
*/
401+
bool capable(int cap)
402+
{
403+
return ns_capable(&init_user_ns, cap);
404+
}
405+
EXPORT_SYMBOL(capable);
406+
#endif /* CONFIG_MULTIUSER */
407+
389408
/**
390409
* file_ns_capable - Determine if the file's opener had a capability in effect
391410
* @file: The file we want to check
@@ -411,22 +430,6 @@ bool file_ns_capable(const struct file *file, struct user_namespace *ns,
411430
}
412431
EXPORT_SYMBOL(file_ns_capable);
413432

414-
/**
415-
* capable - Determine if the current task has a superior capability in effect
416-
* @cap: The capability to be tested for
417-
*
418-
* Return true if the current task has the given superior capability currently
419-
* available for use, false if not.
420-
*
421-
* This sets PF_SUPERPRIV on the task if the capability is available on the
422-
* assumption that it's about to be used.
423-
*/
424-
bool capable(int cap)
425-
{
426-
return ns_capable(&init_user_ns, cap);
427-
}
428-
EXPORT_SYMBOL(capable);
429-
430433
/**
431434
* capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped
432435
* @inode: The inode in question

0 commit comments

Comments
 (0)