aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/capability.h4
-rw-r--r--include/linux/security.h7
-rw-r--r--kernel/capability.c5
-rw-r--r--kernel/sysctl.c8
-rw-r--r--kernel/sysctl_check.c5
-rw-r--r--security/commoncap.c59
-rw-r--r--security/dummy.c16
7 files changed, 80 insertions, 24 deletions
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 8961e7fb755c..7a8d7ade28a0 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -310,10 +310,6 @@ typedef __u32 kernel_cap_t;
310#define CAP_SETFCAP 31 310#define CAP_SETFCAP 31
311 311
312#ifdef __KERNEL__ 312#ifdef __KERNEL__
313/*
314 * Bounding set
315 */
316extern kernel_cap_t cap_bset;
317 313
318/* 314/*
319 * Internal kernel functions only 315 * Internal kernel functions only
diff --git a/include/linux/security.h b/include/linux/security.h
index 9b0b63c50f44..ff3f857f6957 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -34,6 +34,13 @@
34#include <linux/xfrm.h> 34#include <linux/xfrm.h>
35#include <net/flow.h> 35#include <net/flow.h>
36 36
37/*
38 * Bounding set
39 */
40extern kernel_cap_t cap_bset;
41
42extern unsigned securebits;
43
37struct ctl_table; 44struct ctl_table;
38 45
39/* 46/*
diff --git a/kernel/capability.c b/kernel/capability.c
index 4e350a36ed6a..14853be5944d 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 1997 Andrew Main <zefram@fysh.org> 4 * Copyright (C) 1997 Andrew Main <zefram@fysh.org>
5 * 5 *
6 * Integrated into 2.1.97+, Andrew G. Morgan <morgan@transmeta.com> 6 * Integrated into 2.1.97+, Andrew G. Morgan <morgan@kernel.org>
7 * 30 May 2002: Cleanup, Robert M. Love <rml@tech9.net> 7 * 30 May 2002: Cleanup, Robert M. Love <rml@tech9.net>
8 */ 8 */
9 9
@@ -14,9 +14,6 @@
14#include <linux/syscalls.h> 14#include <linux/syscalls.h>
15#include <asm/uaccess.h> 15#include <asm/uaccess.h>
16 16
17unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
18kernel_cap_t cap_bset = CAP_INIT_EFF_SET;
19
20/* 17/*
21 * This lock protects task->cap_* for all tasks including current. 18 * This lock protects task->cap_* for all tasks including current.
22 * Locking rule: acquire this prior to tasklist_lock. 19 * Locking rule: acquire this prior to tasklist_lock.
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c25e67e19af7..067554bda8b7 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -24,7 +24,7 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/sysctl.h> 25#include <linux/sysctl.h>
26#include <linux/proc_fs.h> 26#include <linux/proc_fs.h>
27#include <linux/capability.h> 27#include <linux/security.h>
28#include <linux/ctype.h> 28#include <linux/ctype.h>
29#include <linux/utsname.h> 29#include <linux/utsname.h>
30#include <linux/smp_lock.h> 30#include <linux/smp_lock.h>
@@ -371,6 +371,7 @@ static struct ctl_table kern_table[] = {
371 .proc_handler = &proc_dointvec_taint, 371 .proc_handler = &proc_dointvec_taint,
372 }, 372 },
373#endif 373#endif
374#ifdef CONFIG_SECURITY_CAPABILITIES
374 { 375 {
375 .procname = "cap-bound", 376 .procname = "cap-bound",
376 .data = &cap_bset, 377 .data = &cap_bset,
@@ -378,6 +379,7 @@ static struct ctl_table kern_table[] = {
378 .mode = 0600, 379 .mode = 0600,
379 .proc_handler = &proc_dointvec_bset, 380 .proc_handler = &proc_dointvec_bset,
380 }, 381 },
382#endif /* def CONFIG_SECURITY_CAPABILITIES */
381#ifdef CONFIG_BLK_DEV_INITRD 383#ifdef CONFIG_BLK_DEV_INITRD
382 { 384 {
383 .ctl_name = KERN_REALROOTDEV, 385 .ctl_name = KERN_REALROOTDEV,
@@ -1872,10 +1874,11 @@ static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp,
1872 return 0; 1874 return 0;
1873} 1875}
1874 1876
1877#ifdef CONFIG_SECURITY_CAPABILITIES
1875/* 1878/*
1876 * init may raise the set. 1879 * init may raise the set.
1877 */ 1880 */
1878 1881
1879int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp, 1882int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp,
1880 void __user *buffer, size_t *lenp, loff_t *ppos) 1883 void __user *buffer, size_t *lenp, loff_t *ppos)
1881{ 1884{
@@ -1889,6 +1892,7 @@ int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp,
1889 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, 1892 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
1890 do_proc_dointvec_bset_conv,&op); 1893 do_proc_dointvec_bset_conv,&op);
1891} 1894}
1895#endif /* def CONFIG_SECURITY_CAPABILITIES */
1892 1896
1893/* 1897/*
1894 * Taint values can only be increased 1898 * Taint values can only be increased
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c
index f47c33d17032..3c9ef5a7d575 100644
--- a/kernel/sysctl_check.c
+++ b/kernel/sysctl_check.c
@@ -38,7 +38,10 @@ static struct trans_ctl_table trans_kern_table[] = {
38 { KERN_NODENAME, "hostname" }, 38 { KERN_NODENAME, "hostname" },
39 { KERN_DOMAINNAME, "domainname" }, 39 { KERN_DOMAINNAME, "domainname" },
40 40
41#ifdef CONFIG_SECURITY_CAPABILITIES
41 { KERN_CAP_BSET, "cap-bound" }, 42 { KERN_CAP_BSET, "cap-bound" },
43#endif /* def CONFIG_SECURITY_CAPABILITIES */
44
42 { KERN_PANIC, "panic" }, 45 { KERN_PANIC, "panic" },
43 { KERN_REALROOTDEV, "real-root-dev" }, 46 { KERN_REALROOTDEV, "real-root-dev" },
44 47
@@ -1532,7 +1535,9 @@ int sysctl_check_table(struct ctl_table *table)
1532 (table->strategy == sysctl_ms_jiffies) || 1535 (table->strategy == sysctl_ms_jiffies) ||
1533 (table->proc_handler == proc_dostring) || 1536 (table->proc_handler == proc_dostring) ||
1534 (table->proc_handler == proc_dointvec) || 1537 (table->proc_handler == proc_dointvec) ||
1538#ifdef CONFIG_SECURITY_CAPABILITIES
1535 (table->proc_handler == proc_dointvec_bset) || 1539 (table->proc_handler == proc_dointvec_bset) ||
1540#endif /* def CONFIG_SECURITY_CAPABILITIES */
1536 (table->proc_handler == proc_dointvec_minmax) || 1541 (table->proc_handler == proc_dointvec_minmax) ||
1537 (table->proc_handler == proc_dointvec_jiffies) || 1542 (table->proc_handler == proc_dointvec_jiffies) ||
1538 (table->proc_handler == proc_dointvec_userhz_jiffies) || 1543 (table->proc_handler == proc_dointvec_userhz_jiffies) ||
diff --git a/security/commoncap.c b/security/commoncap.c
index 778cb0cfc5d8..48ca5b092768 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -24,6 +24,25 @@
24#include <linux/hugetlb.h> 24#include <linux/hugetlb.h>
25#include <linux/mount.h> 25#include <linux/mount.h>
26 26
27#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
28/*
29 * Because of the reduced scope of CAP_SETPCAP when filesystem
30 * capabilities are in effect, it is safe to allow this capability to
31 * be available in the default configuration.
32 */
33# define CAP_INIT_BSET CAP_FULL_SET
34#else /* ie. ndef CONFIG_SECURITY_FILE_CAPABILITIES */
35# define CAP_INIT_BSET CAP_INIT_EFF_SET
36#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */
37
38kernel_cap_t cap_bset = CAP_INIT_BSET; /* systemwide capability bound */
39EXPORT_SYMBOL(cap_bset);
40
41/* Global security state */
42
43unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
44EXPORT_SYMBOL(securebits);
45
27int cap_netlink_send(struct sock *sk, struct sk_buff *skb) 46int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
28{ 47{
29 NETLINK_CB(skb).eff_cap = current->cap_effective; 48 NETLINK_CB(skb).eff_cap = current->cap_effective;
@@ -73,14 +92,44 @@ int cap_capget (struct task_struct *target, kernel_cap_t *effective,
73 return 0; 92 return 0;
74} 93}
75 94
95#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
96
97static inline int cap_block_setpcap(struct task_struct *target)
98{
99 /*
100 * No support for remote process capability manipulation with
101 * filesystem capability support.
102 */
103 return (target != current);
104}
105
106static inline int cap_inh_is_capped(void)
107{
108 /*
109 * return 1 if changes to the inheritable set are limited
110 * to the old permitted set.
111 */
112 return !cap_capable(current, CAP_SETPCAP);
113}
114
115#else /* ie., ndef CONFIG_SECURITY_FILE_CAPABILITIES */
116
117static inline int cap_block_setpcap(struct task_struct *t) { return 0; }
118static inline int cap_inh_is_capped(void) { return 1; }
119
120#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */
121
76int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, 122int cap_capset_check (struct task_struct *target, kernel_cap_t *effective,
77 kernel_cap_t *inheritable, kernel_cap_t *permitted) 123 kernel_cap_t *inheritable, kernel_cap_t *permitted)
78{ 124{
79 /* Derived from kernel/capability.c:sys_capset. */ 125 if (cap_block_setpcap(target)) {
80 /* verify restrictions on target's new Inheritable set */ 126 return -EPERM;
81 if (!cap_issubset (*inheritable, 127 }
82 cap_combine (target->cap_inheritable, 128 if (cap_inh_is_capped()
83 current->cap_permitted))) { 129 && !cap_issubset(*inheritable,
130 cap_combine(target->cap_inheritable,
131 current->cap_permitted))) {
132 /* incapable of using this inheritable set */
84 return -EPERM; 133 return -EPERM;
85 } 134 }
86 135
diff --git a/security/dummy.c b/security/dummy.c
index bc43d4c7383e..6d895ade73de 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -37,15 +37,13 @@ static int dummy_capget (struct task_struct *target, kernel_cap_t * effective,
37 kernel_cap_t * inheritable, kernel_cap_t * permitted) 37 kernel_cap_t * inheritable, kernel_cap_t * permitted)
38{ 38{
39 *effective = *inheritable = *permitted = 0; 39 *effective = *inheritable = *permitted = 0;
40 if (!issecure(SECURE_NOROOT)) { 40 if (target->euid == 0) {
41 if (target->euid == 0) { 41 *permitted |= (~0 & ~CAP_FS_MASK);
42 *permitted |= (~0 & ~CAP_FS_MASK); 42 *effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK);
43 *effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK); 43 }
44 } 44 if (target->fsuid == 0) {
45 if (target->fsuid == 0) { 45 *permitted |= CAP_FS_MASK;
46 *permitted |= CAP_FS_MASK; 46 *effective |= CAP_FS_MASK;
47 *effective |= CAP_FS_MASK;
48 }
49 } 47 }
50 return 0; 48 return 0;
51} 49}