2.5.45: Filesystem capabilities
Subsystems (3)
PATCH 1/1 2.5.45: Filesystem capabilities
Hi Linus,
This patch implements filesystem capabilities. It allows to run privileged executables without the need for suid root.
Changes:
- switched from 32 bits to 128 bits for capabilities
I have addressed all objections Al Viro has raised. However, this is not widely tested so far. But this is a relative small patch, so it shouldn't be too hard to remove it later, if it turns out to be too dangerous, either security or file system wise.
Please include.
Regards, Olaf.
fs/Kconfig +53 -0
@@ -1093,6 +1093,59 @@ with or without the generic quota support enabled (CONFIG_QUOTA) - they are completely independent subsystems. +config FS_CAPABILITIES + bool "Filesystem capabilities (Experimental)" + depends on EXPERIMENTAL + help + If you say Y here, you will be able to grant selective privileges to + executables on a needed basis. This means for some executables, + there is no need anymore to run as root or as a suid binary. + + For example, you may drop the SUID bit from ping and grant the + CAP_NET_RAW capability: + # chmod u-s /bin/ping + # chcap cap_net_raw=ep /bin/ping + + Another use would be to run system daemons with their own uid: + # chcap cap_net_bind_service=ei /usr/sbin/named + This sets the effective and inheritable capabilities of named. + + In your startup script: + inhcaps cap_net_bind_service=i bind:bind /usr/sbin/named + + This sets the inheritable set to CAP_NET_BIND_SERVICE, which is + needed in order to bind to port 53, and runs named as user bind + with group bind. + + This allows running named with needed restricted privileges, if the + parent process (root) owns them already. When started by regular + users, named runs without any privileges. + + For user space tools see: + <http://home.t-online.de/home/olaf.dietsche/linux/capability/> + + For libcap and an alternative implementation, based on extended + attributes, see: + <http://www.kernel.org/pub/linux/libs/security/linux-privs/> + + If you're unsure, say N. + +config LIBC_ENABLE_SECURE_HACK + bool "Disable LD_PRELOAD on privileged executables" + depends on FS_CAPABILITIES + help + LD_PRELOAD is a glibc feature, which allows to override system + library functions. But this means also a security hole, through + which an attacker might gain unauthorized privileges. This is + already prevented for SUID and SGID binaries. + + GNU libc doesn't know about filesystem capabilities yet and doesn't + disable LD_PRELOAD for privileged executables, which are not SUID or + SGID. This hack sets the group id to an invalid value and tricks GNU + libc into thinking, this is a SGID binary (unless this is already + SUID and/or SGID). However, this may break some programs. + + If you're unsure, say Y. menu "Network File Systems" depends on NET
fs/Makefile +3 -2
@@ -6,7 +6,7 @@ # export-objs := open.o dcache.o buffer.o bio.o inode.o dquot.o mpage.o aio.o \ - fcntl.o read_write.o dcookies.o fcblist.o + fcntl.o read_write.o dcookies.o fcblist.o fscaps.o obj-y := open.o read_write.o devices.o file_table.o buffer.o \ bio.o super.o block_dev.o char_dev.o stat.o exec.o pipe.o \
@@ -41,7 +41,8 @@ obj-y += devpts/ obj-$(CONFIG_PROFILING) += dcookies.o - +obj-$(CONFIG_FS_CAPABILITIES) += fscaps.o + # Do not add any filesystems before this line obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3 obj-$(CONFIG_JBD) += jbd/
fs/attr.c +4 -0
@@ -13,6 +13,7 @@#include <linux/fcntl.h> #include <linux/quotaops.h> #include <linux/security.h> +#include <linux/fscaps.h> /* Taken over from the old code... */
@@ -170,6 +171,9 @@ }if (!error) {unsigned long dn_mask =setattr_mask (ia_valid); +if (ia_valid & (ATTR_KILL_SUID |ATTR_KILL_SGID )) +fscap_drop (inode); +if (dn_mask)dnotify_parent (dentry, dn_mask); }
fs/fscaps.c +297 -0
297 lines not on this page · raw message
fs/namespace.c +4 -0
@@ -19,6 +19,7 @@#include <linux/seq_file.h> #include <linux/namespace.h> #include <linux/namei.h> +#include <linux/fscaps.h> #include <asm/uaccess.h>
@@ -340,6 +341,7 @@lock_kernel ();DQUOT_OFF (sb);acct_auto_close (sb); +fscap_umount (sb);unlock_kernel (); security_ops->sb_umount_close (mnt);spin_lock (&dcache_lock);
@@ -655,6 +657,8 @@ mnt->mnt_flags = mnt_flags; err =graft_tree (mnt, nd); +if (!err) +fscap_mount (mnt); unlock:up_write (¤t->namespace->sem);mntput (mnt);
fs/open.c +4 -0
@@ -17,6 +17,7 @@#include <linux/namei.h> #include <linux/backing-dev.h> #include <linux/security.h> +#include <linux/fscaps.h> #include <asm/uaccess.h>
@@ -665,6 +666,9 @@ goto cleanup_all; } } + +if (flags &O_CREAT ) +fscap_drop (inode);return f;
fs/super.c +1 -0
@@ -71,6 +71,7 @@ s->s_maxbytes =MAX_NON_LFS ; s->dq_op = sb_dquot_ops; s->s_qcop = sb_quotactl_ops; + s->s_fscaps =NULL ; } out:return s;
include/linux/capability.h +4 -0
@@ -283,6 +283,10 @@#define CAP_LEASE 28 +/* Allow setting capabilities on files */ + +#define CAP_SETFCAP 29 +#ifdef __KERNEL__/* * Bounding set
include/linux/fs.h +1 -0
@@ -667,6 +667,7 @@struct block_device *s_bdev;struct list_head s_instances;struct quota_info s_dquot;/* Diskquota specific options */ +struct fscap_info *s_fscaps;/* Filesystem capability stuff */ char s_id[32 ];/* Informational name */
include/linux/fscaps.h +30 -0
@@ -0,0 +1,30 @@ +/* +* Copyright (c) 2002 Olaf Dietsche +* +* Filesystem capabilities for linux. +*/ + +#ifndef _LINUX_FS_CAPS_H +#define _LINUX_FS_CAPS_H + +#include <linux/config.h> + +struct vfsmount ; +struct super_block ; +struct linux_binprm ; +struct inode ; + +#if defined(CONFIG_FS_CAPABILITIES ) || defined(CONFIG_FS_CAPABILITIES_MODULE ) +extern void fscap_mount (struct vfsmount *mnt); +extern void fscap_umount (struct super_block *sb); +extern void fscap_read (struct linux_binprm *bprm); +extern void fscap_drop (struct inode *inode); +#else +/* !CONFIG_FS_CAPABILITIES */ +static inline void fscap_mount (struct vfsmount *mnt) {} +static inline void fscap_umount (struct super_block *sb) {} +static inline void fscap_read (struct linux_binprm *bprm) {} +static inline void fscap_drop (struct inode *inode) {} +#endif + +#endif
security/capability.c +7 -1
@@ -18,6 +18,7 @@#include <linux/smp_lock.h> #include <linux/skbuff.h> #include <linux/netlink.h> +#include <linux/fscaps.h> /* flag to keep track of how we were registered */ static int secondary;
@@ -119,11 +120,12 @@ {/* 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); +fscap_read (bprm); +/* To support inheritance of root-permissions and suid-root * executables under compatibility mode, we raise all three * capability sets for the file.
@@ -184,6 +186,10 @@ cap_permitted); } } +#ifdef CONFIG_LIBC_ENABLE_SECURE_HACK +if (current->euid == current->uid && current->egid == current->gid) + current->gid =-1 ; +#endif do_unlock =1 ; }
Quoted 8 lines · Olaf Dietsche
Hi Linus,
This patch implements filesystem capabilities. It allows to run privileged executables without the need for suid root.
Changes:
- switched from 32 bits to 128 bits for capabilities
Quoted 8 lines
I have addressed all objections Al Viro has raised. However, this is not widely tested so far. But this is a relative small patch, so it shouldn't be too hard to remove it later, if it turns out to be too dangerous, either security or file system wise.
Please include.
Regards, Olaf.
I second this!
I would very very much like to purge my systems of SUID root binaries.
If this goes in, we/I should start a little project to audit the SUID root binaries commonly found on Linux to see what are the minimum capabilities each binary needs.
Ideally the distro then ship this way by default.
RPM/DPKG (tar,cpio?) should be modified to store the capabilities too.
Dax Kelson
Guru Labs
Hi!
Quoted 4 lines
Hi Linus,
This patch implements filesystem capabilities. It allows to run privileged executables without the need for suid root.
This is gross hack:
fs/fscaps.c line 32
Quoted 9 lines
fs/fscaps.c +9
-0+static char __capname[] =".capabilities" ; + +static int __is_capname (const char *name) +{ +if (*name != __capname[0 ]) +return 0 ; + +return !strcmp (name, __capname); +}
Yup. Magic filename. With ACLs going in 2.5 and with ext2 support for arbitrary metadata, doing capabilities right might be feasible now.
Pavel
Signature · 1 line
When do you have heart between your knees?
Quoted 5 lines · Pavel Machek
Quoted 2 lines
This patch implements filesystem capabilities. It allows to run privileged executables without the need for suid root.
This is gross hack:
Quoted 9 lines
fs/fscaps.c line 32
Quoted 9 lines
fs/fscaps.c +9
-0+static char __capname[] =".capabilities" ; + +static int __is_capname (const char *name) +{ +if (*name != __capname[0 ]) +return 0 ; + +return !strcmp (name, __capname); +}
Of course, this is a hack. A working hack, btw.
Quoted 2 lines
Yup. Magic filename. With ACLs going in 2.5 and with ext2 support for arbitrary metadata, doing capabilities right might be feasible now.
I'm happy to take a look at a working solution.
How come, no one has implemented it yet? :-)
Regards, Olaf.