2.5.44: Filesystem capabilities
Subsystems (3)
RFC PATCH 1/1 2.5.44: Filesystem capabilities
This patch resolves the last issue, access to the capabilities file. Write access is granted for processes, which have the CAP_SETFCAP capability. This is done by wrapping the inode_operations for the root dir and the capability file with appropriate routines.
Although the fs capability patch is complete now, I'm not entirely sure, wether I got everything right. Maybe the security and file system experts may take a look at the code.
As always, I'm running this code myself right now.
Thanks for your time.
Regards, Olaf.
fs/Config.help +47 -0
@@ -1152,3 +1152,50 @@ If unsure, say N. +CONFIG_FS_CAPABILITIES + 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 + 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.
fs/Config.in +3 -0
@@ -108,6 +108,9 @@ define_bool CONFIG_QUOTACTL y fi +dep_bool 'Filesystem capabilities (Experimental)' CONFIG_FS_CAPABILITIES $CONFIG_EXPERIMENTAL +dep_bool ' Disable LD_PRELOAD on privileged executables' CONFIG_LIBC_ENABLE_SECURE_HACK $CONFIG_FS_CAPABILITIES + if [ "$CONFIG_NET" = "y" ]; then mainmenu_option next_comment
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 + fcntl.o read_write.o dcookies.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
@@ -72,6 +72,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
@@ -665,6 +665,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 ; }