2006-11-14 03:07:05

by Serge E. Hallyn

[permalink] [raw]
Subject: security: introduce file caps

From: Serge E. Hallyn <[email protected]>
Subject: [PATCH 1/1] security: introduce file caps

Implement file posix capabilities. This allows programs to be given
a subset of root's powers regardless of who runs them, without
having to use setuid and giving the binary all of root's powers.

This version works with Kaigai Kohei's userspace tools, found at
http://www.kaigai.gr.jp/index.php. For more information on how to
use this patch, Chris Friedhoff has posted a nice page at
http://www.friedhoff.org/fscaps.html.

Changelog:
Nov 13:
Integrate comments from Alexey: Remove CONFIG_ ifdef from
capability.h, and use %zd for printing a size_t.

Nov 13:
Fix endianness warnings by sparse as suggested by Alexey
Dobriyan.

Nov 09:
Address warnings of unused variables at cap_bprm_set_security
when file capabilities are disabled, and simultaneously clean
up the code a little, by pulling the new code into a helper
function.

Nov 08:
For pointers to required userspace tools and how to use
them, see http://www.friedhoff.org/fscaps.html.

Nov 07:
Fix the calculation of the highest bit checked in
check_cap_sanity().

Nov 07:
Allow file caps to be enabled without CONFIG_SECURITY, since
capabilities are the default.
Hook cap_task_setscheduler when !CONFIG_SECURITY.
Move capable(TASK_KILL) to end of cap_task_kill to reduce
audit messages.

Nov 05:
Add secondary calls in selinux/hooks.c to task_setioprio and
task_setscheduler so that selinux and capabilities with file
cap support can be stacked.

Sep 05:
As Seth Arnold points out, uid checks are out of place
for capability code.

Sep 01:
Define task_setscheduler, task_setioprio, cap_task_kill, and
task_setnice to make sure a user cannot affect a process in which
they called a program with some fscaps.

One remaining question is the note under task_setscheduler: are we
ok with CAP_SYS_NICE being sufficient to confine a process to a
cpuset?

It is a semantic change, as without fsccaps, attach_task doesn't
allow CAP_SYS_NICE to override the uid equivalence check. But since
it uses security_task_setscheduler, which elsewhere is used where
CAP_SYS_NICE can be used to override the uid equivalence check,
fixing it might be tough.

task_setscheduler
note: this also controls cpuset:attach_task. Are we ok with
CAP_SYS_NICE being used to confine to a cpuset?
task_setioprio
task_setnice
sys_setpriority uses this (through set_one_prio) for another
process. Need same checks as setrlimit

Aug 21:
Updated secureexec implementation to reflect the fact that
euid and uid might be the same and nonzero, but the process
might still have elevated caps.

Aug 15:
Handle endianness of xattrs.
Enforce capability version match between kernel and disk.
Enforce that no bits beyond the known max capability are
set, else return -EPERM.
With this extra processing, it may be worth reconsidering
doing all the work at bprm_set_security rather than
d_instantiate.

Aug 10:
Always call getxattr at bprm_set_security, rather than
caching it at d_instantiate.

Signed-off-by: Serge E. Hallyn <[email protected]>
---
include/linux/capability.h | 19 +++++
include/linux/security.h | 12 ++-
security/Kconfig | 9 ++
security/capability.c | 4 +
security/commoncap.c | 163 ++++++++++++++++++++++++++++++++++++++++++--
security/selinux/hooks.c | 12 +++
6 files changed, 208 insertions(+), 11 deletions(-)

diff --git a/include/linux/capability.h b/include/linux/capability.h
index 6548b35..9797eee 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -39,12 +39,29 @@ typedef struct __user_cap_data_struct {
__u32 permitted;
__u32 inheritable;
} __user *cap_user_data_t;
+
+
+#define XATTR_CAPS_SUFFIX "capability"
+#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
+struct vfs_cap_data_disk {
+ __le32 version;
+ __le32 effective;
+ __le32 permitted;
+ __le32 inheritable;
+};

#ifdef __KERNEL__

#include <linux/spinlock.h>
#include <asm/current.h>

+struct vfs_cap_data {
+ __u32 version;
+ __u32 effective;
+ __u32 permitted;
+ __u32 inheritable;
+};
+
/* #define STRICT_CAP_T_TYPECHECKS */

#ifdef STRICT_CAP_T_TYPECHECKS
@@ -288,6 +305,8 @@ #define CAP_AUDIT_WRITE 29

#define CAP_AUDIT_CONTROL 30

+#define CAP_NUMCAPS 31
+
#ifdef __KERNEL__
/*
* Bounding set
diff --git a/include/linux/security.h b/include/linux/security.h
index b200b98..2718aeb 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -53,6 +53,10 @@ extern int cap_inode_setxattr(struct den
extern int cap_inode_removexattr(struct dentry *dentry, char *name);
extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
extern void cap_task_reparent_to_init (struct task_struct *p);
+extern int cap_task_kill(struct task_struct *p, struct siginfo *info, int sig, u32 secid);
+extern int cap_task_setscheduler (struct task_struct *p, int policy, struct sched_param *lp);
+extern int cap_task_setioprio (struct task_struct *p, int ioprio);
+extern int cap_task_setnice (struct task_struct *p, int nice);
extern int cap_syslog (int type);
extern int cap_vm_enough_memory (long pages);

@@ -2594,12 +2598,12 @@ static inline int security_task_setgroup

static inline int security_task_setnice (struct task_struct *p, int nice)
{
- return 0;
+ return cap_task_setnice(p, nice);
}

static inline int security_task_setioprio (struct task_struct *p, int ioprio)
{
- return 0;
+ return cap_task_setioprio(p, ioprio);
}

static inline int security_task_getioprio (struct task_struct *p)
@@ -2617,7 +2621,7 @@ static inline int security_task_setsched
int policy,
struct sched_param *lp)
{
- return 0;
+ return cap_task_setscheduler(p, policy, lp);
}

static inline int security_task_getscheduler (struct task_struct *p)
@@ -2634,7 +2638,7 @@ static inline int security_task_kill (st
struct siginfo *info, int sig,
u32 secid)
{
- return 0;
+ return cap_task_kill(p, info, sig, secid);
}

static inline int security_task_wait (struct task_struct *p)
diff --git a/security/Kconfig b/security/Kconfig
index 460e5c9..6c9d69e 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -80,6 +80,15 @@ config SECURITY_CAPABILITIES
This enables the "default" Linux capabilities functionality.
If you are unsure how to answer this question, answer Y.

+config SECURITY_FS_CAPABILITIES
+ bool "File POSIX Capabilities"
+ default n
+ help
+ This enables filesystem capabilities, allowing you to give
+ binaries a subset of root's powers without using setuid 0.
+
+ If in doubt, answer N.
+
config SECURITY_ROOTPLUG
tristate "Root Plug Support"
depends on USB && SECURITY
diff --git a/security/capability.c b/security/capability.c
index b868e7e..14cb592 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -40,6 +40,10 @@ static struct security_operations capabi
.inode_setxattr = cap_inode_setxattr,
.inode_removexattr = cap_inode_removexattr,

+ .task_kill = cap_task_kill,
+ .task_setscheduler = cap_task_setscheduler,
+ .task_setioprio = cap_task_setioprio,
+ .task_setnice = cap_task_setnice,
.task_post_setuid = cap_task_post_setuid,
.task_reparent_to_init = cap_task_reparent_to_init,

diff --git a/security/commoncap.c b/security/commoncap.c
index 5a5ef5c..0e89f1b 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -109,11 +109,95 @@ void cap_capset_set (struct task_struct
target->cap_permitted = *permitted;
}

+#ifdef CONFIG_SECURITY_FS_CAPABILITIES
+static inline void cap_from_disk(struct vfs_cap_data_disk *dcap,
+ struct vfs_cap_data *cap)
+{
+ cap->version = le32_to_cpu(dcap->version);
+ cap->effective = le32_to_cpu(dcap->effective);
+ cap->permitted = le32_to_cpu(dcap->permitted);
+ cap->inheritable = le32_to_cpu(dcap->inheritable);
+}
+
+static int check_cap_sanity(struct vfs_cap_data *cap)
+{
+ int i;
+
+ if (cap->version != _LINUX_CAPABILITY_VERSION)
+ return -EPERM;
+
+ for (i=CAP_NUMCAPS; i<8*sizeof(cap->effective); i++) {
+ if (cap->effective & CAP_TO_MASK(i))
+ return -EPERM;
+ }
+ for (i=CAP_NUMCAPS; i<8*sizeof(cap->permitted); i++) {
+ if (cap->permitted & CAP_TO_MASK(i))
+ return -EPERM;
+ }
+ for (i=CAP_NUMCAPS; i<8*sizeof(cap->inheritable); i++) {
+ if (cap->inheritable & CAP_TO_MASK(i))
+ return -EPERM;
+ }
+
+ return 0;
+}
+
+/* Locate any VFS capabilities: */
+static int set_file_caps(struct linux_binprm *bprm)
+{
+ struct dentry *dentry;
+ ssize_t rc;
+ struct vfs_cap_data_disk dcaps;
+ struct vfs_cap_data caps;
+ struct inode *inode;
+
+ dentry = dget(bprm->file->f_dentry);
+ inode = dentry->d_inode;
+ if (!inode->i_op || !inode->i_op->getxattr) {
+ dput(dentry);
+ return 0;
+ }
+
+ rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, &dcaps,
+ sizeof(dcaps));
+ dput(dentry);
+
+ if (rc == -ENODATA)
+ return 0;
+
+ if (rc < 0) {
+ printk(KERN_NOTICE "%s: Error (%d) getting xattr\n",
+ __FUNCTION__, rc);
+ return rc;
+ }
+
+ if (rc != sizeof(dcaps)) {
+ printk(KERN_NOTICE "%s: got wrong size for getxattr (%zd)\n",
+ __FUNCTION__, rc);
+ return -EPERM;
+ }
+
+ cap_from_disk(&dcaps, &caps);
+ if (check_cap_sanity(&caps))
+ return -EPERM;
+
+ bprm->cap_effective = caps.effective;
+ bprm->cap_permitted = caps.permitted;
+ bprm->cap_inheritable = caps.inheritable;
+
+ return 0;
+}
+#else
+static int set_file_caps(struct linux_binprm *bprm)
+{
+ return 0;
+}
+#endif
+
int cap_bprm_set_security (struct linux_binprm *bprm)
{
/* Copied from fs/exec.c:prepare_binprm. */

- /* We don't have VFS support for capabilities yet */
cap_clear (bprm->cap_inheritable);
cap_clear (bprm->cap_permitted);
cap_clear (bprm->cap_effective);
@@ -134,7 +218,8 @@ int cap_bprm_set_security (struct linux_
if (bprm->e_uid == 0)
cap_set_full (bprm->cap_effective);
}
- return 0;
+
+ return set_file_caps(bprm);
}

void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
@@ -182,11 +267,15 @@ void cap_bprm_apply_creds (struct linux_

int cap_bprm_secureexec (struct linux_binprm *bprm)
{
- /* If/when this module is enhanced to incorporate capability
- bits on files, the test below should be extended to also perform a
- test between the old and new capability sets. For now,
- it simply preserves the legacy decision algorithm used by
- the old userland. */
+ if (current->uid != 0) {
+ if (!cap_isclear(bprm->cap_effective))
+ return 1;
+ if (!cap_isclear(bprm->cap_permitted))
+ return 1;
+ if (!cap_isclear(bprm->cap_inheritable))
+ return 1;
+ }
+
return (current->euid != current->uid ||
current->egid != current->gid);
}
@@ -300,6 +389,62 @@ int cap_task_post_setuid (uid_t old_ruid
return 0;
}

+/*
+ * Rationale: code calling task_setscheduler, task_setioprio, and
+ * task_setnice, assumes that
+ * . if capable(cap_sys_nice), then those actions should be allowed
+ * . if not capable(cap_sys_nice), but acting on your own processes,
+ * then those actions should be allowed
+ * This is insufficient now since you can call code without suid, but
+ * yet with increased caps.
+ * So we check for increased caps on the target process.
+ */
+static inline int cap_safe_nice(struct task_struct *p)
+{
+ if (!cap_issubset(p->cap_permitted, current->cap_permitted) &&
+ !__capable(current, CAP_SYS_NICE))
+ return -EPERM;
+ return 0;
+}
+
+int cap_task_setscheduler (struct task_struct *p, int policy,
+ struct sched_param *lp)
+{
+ return cap_safe_nice(p);
+}
+
+int cap_task_setioprio (struct task_struct *p, int ioprio)
+{
+ return cap_safe_nice(p);
+}
+
+int cap_task_setnice (struct task_struct *p, int nice)
+{
+ return cap_safe_nice(p);
+}
+
+int cap_task_kill(struct task_struct *p, struct siginfo *info,
+ int sig, u32 secid)
+{
+ if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info)))
+ return 0;
+
+ if (secid)
+ /*
+ * Signal sent as a particular user.
+ * Capabilities are ignored. May be wrong, but it's the
+ * only thing we can do at the moment.
+ * Used only by usb drivers?
+ */
+ return 0;
+ if (cap_issubset(p->cap_permitted, current->cap_permitted))
+ return 0;
+ if (capable(CAP_KILL))
+ return 0;
+
+ return -EPERM;
+}
+
void cap_task_reparent_to_init (struct task_struct *p)
{
p->cap_effective = CAP_INIT_EFF_SET;
@@ -337,6 +482,10 @@ EXPORT_SYMBOL(cap_bprm_secureexec);
EXPORT_SYMBOL(cap_inode_setxattr);
EXPORT_SYMBOL(cap_inode_removexattr);
EXPORT_SYMBOL(cap_task_post_setuid);
+EXPORT_SYMBOL(cap_task_kill);
+EXPORT_SYMBOL(cap_task_setscheduler);
+EXPORT_SYMBOL(cap_task_setioprio);
+EXPORT_SYMBOL(cap_task_setnice);
EXPORT_SYMBOL(cap_task_reparent_to_init);
EXPORT_SYMBOL(cap_syslog);
EXPORT_SYMBOL(cap_vm_enough_memory);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8ab5679..2fcc60f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2775,6 +2775,12 @@ static int selinux_task_setnice(struct t

static int selinux_task_setioprio(struct task_struct *p, int ioprio)
{
+ int rc;
+
+ rc = secondary_ops->task_setioprio(p, ioprio);
+ if (rc)
+ return rc;
+
return task_has_perm(current, p, PROCESS__SETSCHED);
}

@@ -2804,6 +2810,12 @@ static int selinux_task_setrlimit(unsign

static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp)
{
+ int rc;
+
+ rc = secondary_ops->task_setscheduler(p, policy, lp);
+ if (rc)
+ return rc;
+
return task_has_perm(current, p, PROCESS__SETSCHED);
}

--
1.4.1


2006-11-15 08:55:31

by Chris Friedhoff

[permalink] [raw]
Subject: Re: security: introduce file caps

Integrates, compiles and runs successfully on 2.6.18.2 ...
so the System keeps on humming ...
the page http://www.friedhoff.org/fscaps.html is updated ...
congratulations for the acceptance in the 2.6.19-rc5-mm2 tree ...

Chris


On Mon, 13 Nov 2006 21:06:55 -0600
"Serge E. Hallyn" <[email protected]> wrote:

> From: Serge E. Hallyn <[email protected]>
> Subject: [PATCH 1/1] security: introduce file caps
>
> Implement file posix capabilities. This allows programs to be given
> a subset of root's powers regardless of who runs them, without
> having to use setuid and giving the binary all of root's powers.
>
> This version works with Kaigai Kohei's userspace tools, found at
> http://www.kaigai.gr.jp/index.php. For more information on how to
> use this patch, Chris Friedhoff has posted a nice page at
> http://www.friedhoff.org/fscaps.html.
>
> Changelog:
> Nov 13:
> Integrate comments from Alexey: Remove CONFIG_ ifdef from
> capability.h, and use %zd for printing a size_t.
>
> Nov 13:
> Fix endianness warnings by sparse as suggested by Alexey
> Dobriyan.
>
> Nov 09:
> Address warnings of unused variables at cap_bprm_set_security
> when file capabilities are disabled, and simultaneously clean
> up the code a little, by pulling the new code into a helper
> function.
>
> Nov 08:
> For pointers to required userspace tools and how to use
> them, see http://www.friedhoff.org/fscaps.html.
>
> Nov 07:
> Fix the calculation of the highest bit checked in
> check_cap_sanity().
>
> Nov 07:
> Allow file caps to be enabled without CONFIG_SECURITY, since
> capabilities are the default.
> Hook cap_task_setscheduler when !CONFIG_SECURITY.
> Move capable(TASK_KILL) to end of cap_task_kill to reduce
> audit messages.
>
> Nov 05:
> Add secondary calls in selinux/hooks.c to task_setioprio and
> task_setscheduler so that selinux and capabilities with file
> cap support can be stacked.
>
> Sep 05:
> As Seth Arnold points out, uid checks are out of place
> for capability code.
>
> Sep 01:
> Define task_setscheduler, task_setioprio, cap_task_kill, and
> task_setnice to make sure a user cannot affect a process in which
> they called a program with some fscaps.
>
> One remaining question is the note under task_setscheduler: are we
> ok with CAP_SYS_NICE being sufficient to confine a process to a
> cpuset?
>
> It is a semantic change, as without fsccaps, attach_task doesn't
> allow CAP_SYS_NICE to override the uid equivalence check. But since
> it uses security_task_setscheduler, which elsewhere is used where
> CAP_SYS_NICE can be used to override the uid equivalence check,
> fixing it might be tough.
>
> task_setscheduler
> note: this also controls cpuset:attach_task. Are we ok with
> CAP_SYS_NICE being used to confine to a cpuset?
> task_setioprio
> task_setnice
> sys_setpriority uses this (through set_one_prio) for another
> process. Need same checks as setrlimit
>
> Aug 21:
> Updated secureexec implementation to reflect the fact that
> euid and uid might be the same and nonzero, but the process
> might still have elevated caps.
>
> Aug 15:
> Handle endianness of xattrs.
> Enforce capability version match between kernel and disk.
> Enforce that no bits beyond the known max capability are
> set, else return -EPERM.
> With this extra processing, it may be worth reconsidering
> doing all the work at bprm_set_security rather than
> d_instantiate.
>
> Aug 10:
> Always call getxattr at bprm_set_security, rather than
> caching it at d_instantiate.
>
> Signed-off-by: Serge E. Hallyn <[email protected]>
> ---
> include/linux/capability.h | 19 +++++
> include/linux/security.h | 12 ++-
> security/Kconfig | 9 ++
> security/capability.c | 4 +
> security/commoncap.c | 163 ++++++++++++++++++++++++++++++++++++++++++--
> security/selinux/hooks.c | 12 +++
> 6 files changed, 208 insertions(+), 11 deletions(-)
>
> diff --git a/include/linux/capability.h b/include/linux/capability.h
> index 6548b35..9797eee 100644
> --- a/include/linux/capability.h
> +++ b/include/linux/capability.h
> @@ -39,12 +39,29 @@ typedef struct __user_cap_data_struct {
> __u32 permitted;
> __u32 inheritable;
> } __user *cap_user_data_t;
> +
> +
> +#define XATTR_CAPS_SUFFIX "capability"
> +#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
> +struct vfs_cap_data_disk {
> + __le32 version;
> + __le32 effective;
> + __le32 permitted;
> + __le32 inheritable;
> +};
>
> #ifdef __KERNEL__
>
> #include <linux/spinlock.h>
> #include <asm/current.h>
>
> +struct vfs_cap_data {
> + __u32 version;
> + __u32 effective;
> + __u32 permitted;
> + __u32 inheritable;
> +};
> +
> /* #define STRICT_CAP_T_TYPECHECKS */
>
> #ifdef STRICT_CAP_T_TYPECHECKS
> @@ -288,6 +305,8 @@ #define CAP_AUDIT_WRITE 29
>
> #define CAP_AUDIT_CONTROL 30
>
> +#define CAP_NUMCAPS 31
> +
> #ifdef __KERNEL__
> /*
> * Bounding set
> diff --git a/include/linux/security.h b/include/linux/security.h
> index b200b98..2718aeb 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -53,6 +53,10 @@ extern int cap_inode_setxattr(struct den
> extern int cap_inode_removexattr(struct dentry *dentry, char *name);
> extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
> extern void cap_task_reparent_to_init (struct task_struct *p);
> +extern int cap_task_kill(struct task_struct *p, struct siginfo *info, int sig, u32 secid);
> +extern int cap_task_setscheduler (struct task_struct *p, int policy, struct sched_param *lp);
> +extern int cap_task_setioprio (struct task_struct *p, int ioprio);
> +extern int cap_task_setnice (struct task_struct *p, int nice);
> extern int cap_syslog (int type);
> extern int cap_vm_enough_memory (long pages);
>
> @@ -2594,12 +2598,12 @@ static inline int security_task_setgroup
>
> static inline int security_task_setnice (struct task_struct *p, int nice)
> {
> - return 0;
> + return cap_task_setnice(p, nice);
> }
>
> static inline int security_task_setioprio (struct task_struct *p, int ioprio)
> {
> - return 0;
> + return cap_task_setioprio(p, ioprio);
> }
>
> static inline int security_task_getioprio (struct task_struct *p)
> @@ -2617,7 +2621,7 @@ static inline int security_task_setsched
> int policy,
> struct sched_param *lp)
> {
> - return 0;
> + return cap_task_setscheduler(p, policy, lp);
> }
>
> static inline int security_task_getscheduler (struct task_struct *p)
> @@ -2634,7 +2638,7 @@ static inline int security_task_kill (st
> struct siginfo *info, int sig,
> u32 secid)
> {
> - return 0;
> + return cap_task_kill(p, info, sig, secid);
> }
>
> static inline int security_task_wait (struct task_struct *p)
> diff --git a/security/Kconfig b/security/Kconfig
> index 460e5c9..6c9d69e 100644
> --- a/security/Kconfig
> +++ b/security/Kconfig
> @@ -80,6 +80,15 @@ config SECURITY_CAPABILITIES
> This enables the "default" Linux capabilities functionality.
> If you are unsure how to answer this question, answer Y.
>
> +config SECURITY_FS_CAPABILITIES
> + bool "File POSIX Capabilities"
> + default n
> + help
> + This enables filesystem capabilities, allowing you to give
> + binaries a subset of root's powers without using setuid 0.
> +
> + If in doubt, answer N.
> +
> config SECURITY_ROOTPLUG
> tristate "Root Plug Support"
> depends on USB && SECURITY
> diff --git a/security/capability.c b/security/capability.c
> index b868e7e..14cb592 100644
> --- a/security/capability.c
> +++ b/security/capability.c
> @@ -40,6 +40,10 @@ static struct security_operations capabi
> .inode_setxattr = cap_inode_setxattr,
> .inode_removexattr = cap_inode_removexattr,
>
> + .task_kill = cap_task_kill,
> + .task_setscheduler = cap_task_setscheduler,
> + .task_setioprio = cap_task_setioprio,
> + .task_setnice = cap_task_setnice,
> .task_post_setuid = cap_task_post_setuid,
> .task_reparent_to_init = cap_task_reparent_to_init,
>
> diff --git a/security/commoncap.c b/security/commoncap.c
> index 5a5ef5c..0e89f1b 100644
> --- a/security/commoncap.c
> +++ b/security/commoncap.c
> @@ -109,11 +109,95 @@ void cap_capset_set (struct task_struct
> target->cap_permitted = *permitted;
> }
>
> +#ifdef CONFIG_SECURITY_FS_CAPABILITIES
> +static inline void cap_from_disk(struct vfs_cap_data_disk *dcap,
> + struct vfs_cap_data *cap)
> +{
> + cap->version = le32_to_cpu(dcap->version);
> + cap->effective = le32_to_cpu(dcap->effective);
> + cap->permitted = le32_to_cpu(dcap->permitted);
> + cap->inheritable = le32_to_cpu(dcap->inheritable);
> +}
> +
> +static int check_cap_sanity(struct vfs_cap_data *cap)
> +{
> + int i;
> +
> + if (cap->version != _LINUX_CAPABILITY_VERSION)
> + return -EPERM;
> +
> + for (i=CAP_NUMCAPS; i<8*sizeof(cap->effective); i++) {
> + if (cap->effective & CAP_TO_MASK(i))
> + return -EPERM;
> + }
> + for (i=CAP_NUMCAPS; i<8*sizeof(cap->permitted); i++) {
> + if (cap->permitted & CAP_TO_MASK(i))
> + return -EPERM;
> + }
> + for (i=CAP_NUMCAPS; i<8*sizeof(cap->inheritable); i++) {
> + if (cap->inheritable & CAP_TO_MASK(i))
> + return -EPERM;
> + }
> +
> + return 0;
> +}
> +
> +/* Locate any VFS capabilities: */
> +static int set_file_caps(struct linux_binprm *bprm)
> +{
> + struct dentry *dentry;
> + ssize_t rc;
> + struct vfs_cap_data_disk dcaps;
> + struct vfs_cap_data caps;
> + struct inode *inode;
> +
> + dentry = dget(bprm->file->f_dentry);
> + inode = dentry->d_inode;
> + if (!inode->i_op || !inode->i_op->getxattr) {
> + dput(dentry);
> + return 0;
> + }
> +
> + rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, &dcaps,
> + sizeof(dcaps));
> + dput(dentry);
> +
> + if (rc == -ENODATA)
> + return 0;
> +
> + if (rc < 0) {
> + printk(KERN_NOTICE "%s: Error (%d) getting xattr\n",
> + __FUNCTION__, rc);
> + return rc;
> + }
> +
> + if (rc != sizeof(dcaps)) {
> + printk(KERN_NOTICE "%s: got wrong size for getxattr (%zd)\n",
> + __FUNCTION__, rc);
> + return -EPERM;
> + }
> +
> + cap_from_disk(&dcaps, &caps);
> + if (check_cap_sanity(&caps))
> + return -EPERM;
> +
> + bprm->cap_effective = caps.effective;
> + bprm->cap_permitted = caps.permitted;
> + bprm->cap_inheritable = caps.inheritable;
> +
> + return 0;
> +}
> +#else
> +static int set_file_caps(struct linux_binprm *bprm)
> +{
> + return 0;
> +}
> +#endif
> +
> int cap_bprm_set_security (struct linux_binprm *bprm)
> {
> /* Copied from fs/exec.c:prepare_binprm. */
>
> - /* We don't have VFS support for capabilities yet */
> cap_clear (bprm->cap_inheritable);
> cap_clear (bprm->cap_permitted);
> cap_clear (bprm->cap_effective);
> @@ -134,7 +218,8 @@ int cap_bprm_set_security (struct linux_
> if (bprm->e_uid == 0)
> cap_set_full (bprm->cap_effective);
> }
> - return 0;
> +
> + return set_file_caps(bprm);
> }
>
> void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
> @@ -182,11 +267,15 @@ void cap_bprm_apply_creds (struct linux_
>
> int cap_bprm_secureexec (struct linux_binprm *bprm)
> {
> - /* If/when this module is enhanced to incorporate capability
> - bits on files, the test below should be extended to also perform a
> - test between the old and new capability sets. For now,
> - it simply preserves the legacy decision algorithm used by
> - the old userland. */
> + if (current->uid != 0) {
> + if (!cap_isclear(bprm->cap_effective))
> + return 1;
> + if (!cap_isclear(bprm->cap_permitted))
> + return 1;
> + if (!cap_isclear(bprm->cap_inheritable))
> + return 1;
> + }
> +
> return (current->euid != current->uid ||
> current->egid != current->gid);
> }
> @@ -300,6 +389,62 @@ int cap_task_post_setuid (uid_t old_ruid
> return 0;
> }
>
> +/*
> + * Rationale: code calling task_setscheduler, task_setioprio, and
> + * task_setnice, assumes that
> + * . if capable(cap_sys_nice), then those actions should be allowed
> + * . if not capable(cap_sys_nice), but acting on your own processes,
> + * then those actions should be allowed
> + * This is insufficient now since you can call code without suid, but
> + * yet with increased caps.
> + * So we check for increased caps on the target process.
> + */
> +static inline int cap_safe_nice(struct task_struct *p)
> +{
> + if (!cap_issubset(p->cap_permitted, current->cap_permitted) &&
> + !__capable(current, CAP_SYS_NICE))
> + return -EPERM;
> + return 0;
> +}
> +
> +int cap_task_setscheduler (struct task_struct *p, int policy,
> + struct sched_param *lp)
> +{
> + return cap_safe_nice(p);
> +}
> +
> +int cap_task_setioprio (struct task_struct *p, int ioprio)
> +{
> + return cap_safe_nice(p);
> +}
> +
> +int cap_task_setnice (struct task_struct *p, int nice)
> +{
> + return cap_safe_nice(p);
> +}
> +
> +int cap_task_kill(struct task_struct *p, struct siginfo *info,
> + int sig, u32 secid)
> +{
> + if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info)))
> + return 0;
> +
> + if (secid)
> + /*
> + * Signal sent as a particular user.
> + * Capabilities are ignored. May be wrong, but it's the
> + * only thing we can do at the moment.
> + * Used only by usb drivers?
> + */
> + return 0;
> + if (cap_issubset(p->cap_permitted, current->cap_permitted))
> + return 0;
> + if (capable(CAP_KILL))
> + return 0;
> +
> + return -EPERM;
> +}
> +
> void cap_task_reparent_to_init (struct task_struct *p)
> {
> p->cap_effective = CAP_INIT_EFF_SET;
> @@ -337,6 +482,10 @@ EXPORT_SYMBOL(cap_bprm_secureexec);
> EXPORT_SYMBOL(cap_inode_setxattr);
> EXPORT_SYMBOL(cap_inode_removexattr);
> EXPORT_SYMBOL(cap_task_post_setuid);
> +EXPORT_SYMBOL(cap_task_kill);
> +EXPORT_SYMBOL(cap_task_setscheduler);
> +EXPORT_SYMBOL(cap_task_setioprio);
> +EXPORT_SYMBOL(cap_task_setnice);
> EXPORT_SYMBOL(cap_task_reparent_to_init);
> EXPORT_SYMBOL(cap_syslog);
> EXPORT_SYMBOL(cap_vm_enough_memory);
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 8ab5679..2fcc60f 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2775,6 +2775,12 @@ static int selinux_task_setnice(struct t
>
> static int selinux_task_setioprio(struct task_struct *p, int ioprio)
> {
> + int rc;
> +
> + rc = secondary_ops->task_setioprio(p, ioprio);
> + if (rc)
> + return rc;
> +
> return task_has_perm(current, p, PROCESS__SETSCHED);
> }
>
> @@ -2804,6 +2810,12 @@ static int selinux_task_setrlimit(unsign
>
> static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp)
> {
> + int rc;
> +
> + rc = secondary_ops->task_setscheduler(p, policy, lp);
> + if (rc)
> + return rc;
> +
> return task_has_perm(current, p, PROCESS__SETSCHED);
> }
>
> --
> 1.4.1
>


--------------------
Chris Friedhoff
[email protected]

2006-11-23 08:16:27

by Andrew Morton

[permalink] [raw]
Subject: Re: security: introduce file caps

On Mon, 13 Nov 2006 21:06:55 -0600
"Serge E. Hallyn" <[email protected]> wrote:

> Implement file posix capabilities. This allows programs to be given
> a subset of root's powers regardless of who runs them, without
> having to use setuid and giving the binary all of root's powers.

With this patch applied, my X server fails to exit when I do the normal
logout thing from the KDE menus.

The distro is FC5, SELinux is enabled. I start X via `startx'.

All the X clients have gone away, but the server continues to run. Black
screen with just a mouse pointer which still responds to movement.

This happens with CONFIG_SECURITY_FS_CAPABILITIES=n as well as =y.

ps auxfw says:

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.0 2000 676 ? Ss 01:04 0:00 init [3]
root 2 0.0 0.0 0 0 ? SN 01:04 0:00 [ksoftirqd/0]
root 3 0.0 0.0 0 0 ? S 01:04 0:00 [watchdog/0]
root 4 0.0 0.0 0 0 ? S< 01:04 0:00 [events/0]
root 5 0.0 0.0 0 0 ? S< 01:04 0:00 [khelper]
root 6 0.0 0.0 0 0 ? S< 01:04 0:00 [kthread]
root 47 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [kblockd/0]
root 48 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [kacpid]
root 152 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [ata/0]
root 153 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [ata_aux]
root 154 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [ksuspend_usbd]
root 157 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [khubd]
root 159 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [kseriod]
root 179 0.0 0.0 0 0 ? S 01:04 0:00 \_ [pdflush]
root 180 0.0 0.0 0 0 ? S 01:04 0:00 \_ [pdflush]
root 181 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [kswapd0]
root 182 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [aio/0]
root 291 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [scsi_eh_0]
root 292 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [scsi_eh_1]
root 297 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [scsi_eh_2]
root 298 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [scsi_eh_3]
root 311 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [pccardd]
root 321 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [kpsmoused]
root 326 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [kedac]
root 354 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [kjournald]
root 740 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [hda_codec]
root 975 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [khpsbpkt]
root 1110 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [knodemgrd_0]
root 1680 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [kauditd]
root 2237 0.0 0.0 0 0 ? S< 01:04 0:00 \_ [ipw2200/0]
root 421 0.0 0.0 2212 648 ? S<s 01:04 0:00 /sbin/udevd -d
root 1427 0.0 0.0 1584 280 ? Ss 01:04 0:00 cpuspeed -d -n
root 1624 0.0 0.0 1652 592 ? Ss 01:04 0:00 syslogd -m 0
root 1627 0.0 0.0 1604 392 ? Ss 01:04 0:00 klogd -x
rpc 1644 0.0 0.0 1736 552 ? Ss 01:04 0:00 portmap
rpcuser 1663 0.0 0.0 1744 716 ? Ss 01:04 0:00 rpc.statd
root 1678 0.0 0.0 9944 604 ? S<sl 01:04 0:00 auditd
root 1707 0.0 0.0 4728 584 ? Ss 01:04 0:00 rpc.idmapd
dbus 1721 0.0 0.1 11268 1104 ? Ssl 01:04 0:00 dbus-daemon --system
root 1763 0.0 0.0 1820 460 ? Ss 01:04 0:00 /usr/bin/hidd --server
root 1850 0.0 0.0 1872 748 ? Ss 01:04 0:00 /usr/sbin/automount --timeout=60 --debug /net program /etc/auto.net
root 1863 0.0 0.0 1600 460 ? Ss 01:04 0:00 /usr/sbin/acpid
root 1872 0.0 0.0 5008 488 ? Ss 01:04 0:00 ./hpiod
root 1877 0.0 0.4 12572 4720 ? S 01:04 0:00 python ./hpssd.py
root 1888 0.0 0.1 4984 1100 ? Ss 01:04 0:00 /usr/sbin/sshd
root 2354 0.0 0.2 7800 2516 ? Ss 01:04 0:00 \_ sshd: akpm [priv]
akpm 2408 0.0 0.1 7928 1964 ? S 01:04 0:00 | \_ sshd: akpm@pts/0
akpm 2443 0.0 0.2 5872 2364 pts/0 Ss+ 01:04 0:00 | \_ -zsh
root 3198 0.0 0.2 7800 2512 ? Ss 01:05 0:00 \_ sshd: akpm [priv]
akpm 3202 0.0 0.1 7928 2004 ? S 01:05 0:00 \_ sshd: akpm@pts/1
akpm 3209 0.0 0.2 6004 2568 pts/1 Ss 01:05 0:00 \_ -zsh
akpm 3264 0.0 0.0 2104 840 pts/1 R+ 01:11 0:00 \_ ps auxfw
root 1900 0.0 0.0 2228 808 ? Ss 01:04 0:00 xinetd -stayalive -pidfile /var/run/xinetd.pid
ntp 1912 0.0 0.4 4244 4244 ? SLs 01:04 0:00 ntpd -u ntp:ntp -p /var/run/ntpd.pid -g
root 1957 0.0 0.0 1824 344 ? Ss 01:04 0:00 gpm -m /dev/input/mice -t exps2
root 1966 0.0 0.1 5188 1192 ? Ss 01:04 0:00 crond
xfs 2001 0.1 0.2 4204 2492 ? Ss 01:04 0:00 xfs -droppriv -daemon
root 2010 0.0 0.0 1596 496 ? SNs 01:04 0:00 anacron -s
root 2018 0.0 0.0 2164 444 ? Ss 01:04 0:00 /usr/sbin/atd
root 2027 0.0 0.1 3136 1152 ? Ss 01:04 0:00 cups-config-daemon
68 2037 0.6 0.3 5100 3436 ? Ss 01:04 0:02 hald
root 2038 0.0 0.1 3136 1048 ? S 01:04 0:00 \_ hald-runner
68 2044 0.0 0.0 2236 868 ? S 01:04 0:00 \_ /usr/libexec/hald-addon-acpi
68 2052 0.0 0.0 2236 872 ? S 01:04 0:00 \_ /usr/libexec/hald-addon-keyboard
root 2127 0.0 0.1 2744 1316 ? Ss 01:04 0:00 login -- akpm
akpm 2453 0.0 0.2 5968 2492 tty1 Ss+ 01:04 0:00 \_ -zsh
root 2128 0.0 0.0 1588 408 tty2 Ss+ 01:04 0:00 /sbin/mingetty tty2
root 2129 0.0 0.0 1588 408 tty3 Ss+ 01:04 0:00 /sbin/mingetty tty3
root 2130 0.0 0.0 1584 404 tty4 Ss+ 01:04 0:00 /sbin/mingetty tty4
root 2131 0.0 0.0 1584 404 tty5 Ss+ 01:04 0:00 /sbin/mingetty tty5
root 2132 0.0 0.0 1584 404 tty6 Ss+ 01:04 0:00 /sbin/mingetty tty6
root 2753 0.0 0.1 8364 1928 ? Ss 01:05 0:00 sendmail: accepting connections
smmsp 2764 0.0 0.1 7344 1712 ? Ss 01:05 0:00 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue
root 2784 0.7 0.8 13284 8428 tty7 Ss+ 01:05 0:02 X :0 -auth /home/akpm/.serverauth.2767
akpm 2948 0.0 0.0 2864 264 ? Ss 01:05 0:00 syndaemon -k -i 1 -d

2006-11-23 08:25:37

by Andrew Morton

[permalink] [raw]
Subject: Re: security: introduce file caps

On Thu, 23 Nov 2006 00:14:58 -0800
Andrew Morton <[email protected]> wrote:

> On Mon, 13 Nov 2006 21:06:55 -0600
> "Serge E. Hallyn" <[email protected]> wrote:
>
> > Implement file posix capabilities. This allows programs to be given
> > a subset of root's powers regardless of who runs them, without
> > having to use setuid and giving the binary all of root's powers.
>
> With this patch applied, my X server fails to exit when I do the normal
> logout thing from the KDE menus.

After a manual kill of the X server I see on the VT:

xinit: Operation not permitted (errno 1): Can't kill X server

2006-11-23 18:40:48

by Andrew Morton

[permalink] [raw]
Subject: Re: security: introduce file caps

On Thu, 23 Nov 2006 13:12:03 +0100
Chris Friedhoff <[email protected]> wrote:

> xinit respects capabilities (at least i guess), so when the system has
> capability-support, the binary /usr/X11R6/bin/xinit neeeds the
> capability cap_kill even when no capability extended attribute exists
> for this binary.
>
> setfcaps cap_kill=ep /usr/X11R6/bin/xinit
>
> I documented this here:
> http://www.friedhoff.org/fscaps.html#Xorg,%20xinit,%20xfce,%20kde
>
> and for more:
> http://www.friedhoff.org/fscaps.html
>

Even when CONFIG_SECURITY_FS_CAPABILITIES=n?

2006-11-23 21:42:11

by Serge E. Hallyn

[permalink] [raw]
Subject: Re: security: introduce file caps

Quoting Andrew Morton ([email protected]):
> On Thu, 23 Nov 2006 13:12:03 +0100
> Chris Friedhoff <[email protected]> wrote:
>
> > xinit respects capabilities (at least i guess), so when the system has
> > capability-support, the binary /usr/X11R6/bin/xinit neeeds the
> > capability cap_kill even when no capability extended attribute exists
> > for this binary.
> >
> > setfcaps cap_kill=ep /usr/X11R6/bin/xinit
> >
> > I documented this here:
> > http://www.friedhoff.org/fscaps.html#Xorg,%20xinit,%20xfce,%20kde
> >
> > and for more:
> > http://www.friedhoff.org/fscaps.html
> >
>
> Even when CONFIG_SECURITY_FS_CAPABILITIES=n?

No, the patch shouldn't change behavior when
CONFIG_SECURITY_FS_CAPABILITIES=n, though of course I see why it did. I
will send a fixed patch tomorrow or this weekend.

sorry,
-serge

2006-11-23 23:23:04

by Chris Friedhoff

[permalink] [raw]
Subject: Re: security: introduce file caps

I can confirm this behavior, but only in the interaction of xinit and X.
ping and ntpdate behave with a patched kernel but
CONFIG_SECURITY_FS_CAPABILITIES=n like expected, even with empty or
wrong capabilities. Tested with 2.6.18.3 kernel

Chris



On Thu, 23 Nov 2006 15:41:59 -0600
"Serge E. Hallyn" <[email protected]> wrote:

> Quoting Andrew Morton ([email protected]):
> > On Thu, 23 Nov 2006 13:12:03 +0100
> > Chris Friedhoff <[email protected]> wrote:
> >
> > > xinit respects capabilities (at least i guess), so when the system has
> > > capability-support, the binary /usr/X11R6/bin/xinit neeeds the
> > > capability cap_kill even when no capability extended attribute exists
> > > for this binary.
> > >
> > > setfcaps cap_kill=ep /usr/X11R6/bin/xinit
> > >
> > > I documented this here:
> > > http://www.friedhoff.org/fscaps.html#Xorg,%20xinit,%20xfce,%20kde
> > >
> > > and for more:
> > > http://www.friedhoff.org/fscaps.html
> > >
> >
> > Even when CONFIG_SECURITY_FS_CAPABILITIES=n?
>
> No, the patch shouldn't change behavior when
> CONFIG_SECURITY_FS_CAPABILITIES=n, though of course I see why it did. I
> will send a fixed patch tomorrow or this weekend.
>
> sorry,
> -serge


--------------------
Chris Friedhoff
[email protected]

2006-11-24 16:16:39

by Serge E. Hallyn

[permalink] [raw]
Subject: file caps: permit unsafe signaling when CONFIG_FS_CAPS=n

Ok, the following patch restores the CONFIG_FS_CAPS=n signaling
behavior, but I'm having a config problem. When
CONFIG_SECURITY_CAPABILITIES=n, and I toggle
CONFIG_SECURITY_FS_CAPABILITIES between y and n, security/commoncap.o
does not recompile. However since capabilities are now the default
security module, commoncap.o is in fact included in the kernel build,
and therefore should be recompiled.

Looking into why, but maybe someone knows offhand what would be going
wrong?

thanks,
-serge

From: Serge E. Hallyn <[email protected]>
Subject: [PATCH 1/1] file caps: permit unsafe signaling when CONFIG_FS_CAPS=n

In legacy behavior, when a user starts a setuid program, that user
can send signals to the running program. The file capabilities
patch prevents that not only when file capabilities are enabled,
but in all cases where capabilities are used.

For instance, when starting the X server, which is setuid root, it
is expected that the user who started it be able to kill it.

Existing behavior should not be changed. This patch should reenable
signaling setuid processes started by the signaling user.

Signed-off-by: Serge E. Hallyn <[email protected]>
---
security/commoncap.c | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/security/commoncap.c b/security/commoncap.c
index 0e89f1b..04b277f 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -389,6 +389,7 @@ int cap_task_post_setuid (uid_t old_ruid
return 0;
}

+#ifdef CONFIG_SECURITY_FS_CAPABILITIES
/*
* Rationale: code calling task_setscheduler, task_setioprio, and
* task_setnice, assumes that
@@ -444,6 +445,26 @@ int cap_task_kill(struct task_struct *p,

return -EPERM;
}
+#else
+int cap_task_setscheduler (struct task_struct *p, int policy,
+ struct sched_param *lp)
+{
+ return 0;
+}
+int cap_task_setioprio (struct task_struct *p, int ioprio)
+{
+ return 0;
+}
+int cap_task_setnice (struct task_struct *p, int nice)
+{
+ return 0;
+}
+int cap_task_kill(struct task_struct *p, struct siginfo *info,
+ int sig, u32 secid)
+{
+ return 0;
+}
+#endif

void cap_task_reparent_to_init (struct task_struct *p)
{
--
1.4.1

2006-11-24 18:17:59

by Serge E. Hallyn

[permalink] [raw]
Subject: Re: file caps: permit unsafe signaling when CONFIG_FS_CAPS=n

Quoting Serge E. Hallyn ([email protected]):
> Ok, the following patch restores the CONFIG_FS_CAPS=n signaling
> behavior, but I'm having a config problem. When
> CONFIG_SECURITY_CAPABILITIES=n, and I toggle
> CONFIG_SECURITY_FS_CAPABILITIES between y and n, security/commoncap.o
> does not recompile. However since capabilities are now the default
> security module, commoncap.o is in fact included in the kernel build,
> and therefore should be recompiled.
>
> Looking into why, but maybe someone knows offhand what would be going
> wrong?

Uh, never mind. It does the right thing. CONFIG_SECURITY=n means we
use capabilities, but CONFIG_SECURITY=y and CONFIG_SECURITY_CAPABILITIES=n
means we use dummy. The following patch fixes the Kconfig accordingly.

From: Serge E. Hallyn <[email protected]>
Subject: [PATCH 1/1] file caps: don't show FILE_CAPABILITIES option when not relevant

FILE_CAPABILITIES are relevant when CONFIG_SECURITY=n, but not when
CONFIG_SECURITY=y && CONFIG_SECURITY_CAPABILITIES=n. So make
CONFIG_SECURITY_FS_CAPABILITIES depend on the right conditions.

Signed-off-by: Serge E. Hallyn <[email protected]>
---
security/Kconfig | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/security/Kconfig b/security/Kconfig
index 6c9d69e..1b47f01 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -82,6 +82,7 @@ config SECURITY_CAPABILITIES

config SECURITY_FS_CAPABILITIES
bool "File POSIX Capabilities"
+ depends on SECURITY=n || SECURITY_CAPABILITIES=y
default n
help
This enables filesystem capabilities, allowing you to give
--
1.4.1

2006-11-25 21:21:25

by Chris Friedhoff

[permalink] [raw]
Subject: Re: file caps: permit unsafe signaling when CONFIG_FS_CAPS=n

Serge, may I ask you to send a new complete patch with Andrew Mortons
additions and this change and a new changelog entry.

Thanks
Chris


On Fri, 24 Nov
2006 12:17:42 -0600 "Serge E. Hallyn" <[email protected]> wrote:

> Quoting Serge E. Hallyn ([email protected]):
> > Ok, the following patch restores the CONFIG_FS_CAPS=n signaling
> > behavior, but I'm having a config problem. When
> > CONFIG_SECURITY_CAPABILITIES=n, and I toggle
> > CONFIG_SECURITY_FS_CAPABILITIES between y and n, security/commoncap.o
> > does not recompile. However since capabilities are now the default
> > security module, commoncap.o is in fact included in the kernel build,
> > and therefore should be recompiled.
> >
> > Looking into why, but maybe someone knows offhand what would be going
> > wrong?
>
> Uh, never mind. It does the right thing. CONFIG_SECURITY=n means we
> use capabilities, but CONFIG_SECURITY=y and CONFIG_SECURITY_CAPABILITIES=n
> means we use dummy. The following patch fixes the Kconfig accordingly.
>
> From: Serge E. Hallyn <[email protected]>
> Subject: [PATCH 1/1] file caps: don't show FILE_CAPABILITIES option when not relevant
>
> FILE_CAPABILITIES are relevant when CONFIG_SECURITY=n, but not when
> CONFIG_SECURITY=y && CONFIG_SECURITY_CAPABILITIES=n. So make
> CONFIG_SECURITY_FS_CAPABILITIES depend on the right conditions.
>
> Signed-off-by: Serge E. Hallyn <[email protected]>
> ---
> security/Kconfig | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/security/Kconfig b/security/Kconfig
> index 6c9d69e..1b47f01 100644
> --- a/security/Kconfig
> +++ b/security/Kconfig
> @@ -82,6 +82,7 @@ config SECURITY_CAPABILITIES
>
> config SECURITY_FS_CAPABILITIES
> bool "File POSIX Capabilities"
> + depends on SECURITY=n || SECURITY_CAPABILITIES=y
> default n
> help
> This enables filesystem capabilities, allowing you to give
> --
> 1.4.1
>


--------------------
Chris Friedhoff
[email protected]