diff options
author | Iulia Manda <iulia.manda21@gmail.com> | 2015-04-15 19:16:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-15 19:35:22 -0400 |
commit | 2813893f8b197a14f1e1ddb04d99bce46817c84a (patch) | |
tree | 650651e638f867a6bda23e08c70bdd9857d121ca /kernel | |
parent | c79574abe2baddf569532e7e430e4977771dd25c (diff) |
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>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/Makefile | 4 | ||||
-rw-r--r-- | kernel/capability.c | 35 | ||||
-rw-r--r-- | kernel/cred.c | 3 | ||||
-rw-r--r-- | kernel/groups.c | 3 | ||||
-rw-r--r-- | kernel/sys.c | 2 | ||||
-rw-r--r-- | kernel/sys_ni.c | 14 |
6 files changed, 41 insertions, 20 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index 1408b3353a3c..0f8f8b0bc1bf 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -9,7 +9,9 @@ obj-y = fork.o exec_domain.o panic.o \ | |||
9 | extable.o params.o \ | 9 | extable.o params.o \ |
10 | kthread.o sys_ni.o nsproxy.o \ | 10 | kthread.o sys_ni.o nsproxy.o \ |
11 | notifier.o ksysfs.o cred.o reboot.o \ | 11 | 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 | ||
13 | 15 | ||
14 | ifdef CONFIG_FUNCTION_TRACER | 16 | ifdef CONFIG_FUNCTION_TRACER |
15 | # Do not trace debug files and internal ftrace files | 17 | # Do not trace debug files and internal ftrace files |
diff --git a/kernel/capability.c b/kernel/capability.c index 989f5bfc57dc..45432b54d5c6 100644 --- a/kernel/capability.c +++ b/kernel/capability.c | |||
@@ -35,6 +35,7 @@ static int __init file_caps_disable(char *str) | |||
35 | } | 35 | } |
36 | __setup("no_file_caps", file_caps_disable); | 36 | __setup("no_file_caps", file_caps_disable); |
37 | 37 | ||
38 | #ifdef CONFIG_MULTIUSER | ||
38 | /* | 39 | /* |
39 | * More recent versions of libcap are available from: | 40 | * More recent versions of libcap are available from: |
40 | * | 41 | * |
@@ -386,6 +387,24 @@ bool ns_capable(struct user_namespace *ns, int cap) | |||
386 | } | 387 | } |
387 | EXPORT_SYMBOL(ns_capable); | 388 | EXPORT_SYMBOL(ns_capable); |
388 | 389 | ||
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 | |||
389 | /** | 408 | /** |
390 | * file_ns_capable - Determine if the file's opener had a capability in effect | 409 | * file_ns_capable - Determine if the file's opener had a capability in effect |
391 | * @file: The file we want to check | 410 | * @file: The file we want to check |
@@ -412,22 +431,6 @@ bool file_ns_capable(const struct file *file, struct user_namespace *ns, | |||
412 | EXPORT_SYMBOL(file_ns_capable); | 431 | EXPORT_SYMBOL(file_ns_capable); |
413 | 432 | ||
414 | /** | 433 | /** |
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 | |||
430 | /** | ||
431 | * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped | 434 | * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped |
432 | * @inode: The inode in question | 435 | * @inode: The inode in question |
433 | * @cap: The capability in question | 436 | * @cap: The capability in question |
diff --git a/kernel/cred.c b/kernel/cred.c index e0573a43c7df..ec1c07667ec1 100644 --- a/kernel/cred.c +++ b/kernel/cred.c | |||
@@ -29,6 +29,9 @@ | |||
29 | 29 | ||
30 | static struct kmem_cache *cred_jar; | 30 | static struct kmem_cache *cred_jar; |
31 | 31 | ||
32 | /* init to 2 - one for init_task, one to ensure it is never freed */ | ||
33 | struct group_info init_groups = { .usage = ATOMIC_INIT(2) }; | ||
34 | |||
32 | /* | 35 | /* |
33 | * The initial credentials for the initial task | 36 | * The initial credentials for the initial task |
34 | */ | 37 | */ |
diff --git a/kernel/groups.c b/kernel/groups.c index 664411f171b5..74d431d25251 100644 --- a/kernel/groups.c +++ b/kernel/groups.c | |||
@@ -9,9 +9,6 @@ | |||
9 | #include <linux/user_namespace.h> | 9 | #include <linux/user_namespace.h> |
10 | #include <asm/uaccess.h> | 10 | #include <asm/uaccess.h> |
11 | 11 | ||
12 | /* init to 2 - one for init_task, one to ensure it is never freed */ | ||
13 | struct group_info init_groups = { .usage = ATOMIC_INIT(2) }; | ||
14 | |||
15 | struct group_info *groups_alloc(int gidsetsize) | 12 | struct group_info *groups_alloc(int gidsetsize) |
16 | { | 13 | { |
17 | struct group_info *group_info; | 14 | struct group_info *group_info; |
diff --git a/kernel/sys.c b/kernel/sys.c index a03d9cd23ed7..3be344902316 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -325,6 +325,7 @@ out_unlock: | |||
325 | * SMP: There are not races, the GIDs are checked only by filesystem | 325 | * SMP: There are not races, the GIDs are checked only by filesystem |
326 | * operations (as far as semantic preservation is concerned). | 326 | * operations (as far as semantic preservation is concerned). |
327 | */ | 327 | */ |
328 | #ifdef CONFIG_MULTIUSER | ||
328 | SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid) | 329 | SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid) |
329 | { | 330 | { |
330 | struct user_namespace *ns = current_user_ns(); | 331 | struct user_namespace *ns = current_user_ns(); |
@@ -815,6 +816,7 @@ change_okay: | |||
815 | commit_creds(new); | 816 | commit_creds(new); |
816 | return old_fsgid; | 817 | return old_fsgid; |
817 | } | 818 | } |
819 | #endif /* CONFIG_MULTIUSER */ | ||
818 | 820 | ||
819 | /** | 821 | /** |
820 | * sys_getpid - return the thread group id of the current process | 822 | * sys_getpid - return the thread group id of the current process |
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 5adcb0ae3a58..7995ef5868d8 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c | |||
@@ -159,6 +159,20 @@ cond_syscall(sys_uselib); | |||
159 | cond_syscall(sys_fadvise64); | 159 | cond_syscall(sys_fadvise64); |
160 | cond_syscall(sys_fadvise64_64); | 160 | cond_syscall(sys_fadvise64_64); |
161 | cond_syscall(sys_madvise); | 161 | cond_syscall(sys_madvise); |
162 | cond_syscall(sys_setuid); | ||
163 | cond_syscall(sys_setregid); | ||
164 | cond_syscall(sys_setgid); | ||
165 | cond_syscall(sys_setreuid); | ||
166 | cond_syscall(sys_setresuid); | ||
167 | cond_syscall(sys_getresuid); | ||
168 | cond_syscall(sys_setresgid); | ||
169 | cond_syscall(sys_getresgid); | ||
170 | cond_syscall(sys_setgroups); | ||
171 | cond_syscall(sys_getgroups); | ||
172 | cond_syscall(sys_setfsuid); | ||
173 | cond_syscall(sys_setfsgid); | ||
174 | cond_syscall(sys_capget); | ||
175 | cond_syscall(sys_capset); | ||
162 | 176 | ||
163 | /* arch-specific weak syscall entries */ | 177 | /* arch-specific weak syscall entries */ |
164 | cond_syscall(sys_pciconfig_read); | 178 | cond_syscall(sys_pciconfig_read); |