Fedora and udev

Joshua Brindle jbrindle at tresys.com
Sun Aug 22 15:29:42 UTC 2004


None of this restorecon voodoo nor mount context is necessary when udev 
is implemented correctly.

When we were experimenting with udev it only took ramfs xattr support, 
add ramfs to fs_use as an xattr filesystem and set up udev with selinux 
support. When it runs it creates the nodes and then labels them via the 
libselinux api which reads file_contexts. Aside from the problems I've 
already mentioned there should be no problems running udev.

If the tmpfs context support is something different from this then it 
should not be used (I have not looked at tmpfs support at all but have 
personal experience that ramfs xattr works as expected).

Joshua

Luke Kenneth Casson Leighton wrote:

>On Sun, Aug 22, 2004 at 09:25:38PM +1000, Russell Coker wrote:
>  
>
>>It seems that udev is now virtually mandatory as of the latest rawhide update.
>>
>>udev uses ramfs for /tmp, ramfs (as of the latest Fedora kernel 2.6.8-1.525) 
>>has no support for file labelling and breaks everything.
>>
>>Can we get ramfs labelling working in the next few days or do we have to 
>>change things to not depend on udev?
>>    
>>
> 
> chris pebenito of gentoo/hardened i believe has written a ramfs patch
> already (2.6.6)
>
> it was what i based the shmfs one off of.
>
> or maybe that's the other way round, i dunno.  can't remember.
>
>
> remember that just getting ramfs / tmpfs working is not enough, you
> must also:
>
> - patch selinux/hooks.c to allow mount -o fscontext=system_u:object_r:device_t
>   on a tmpfs or shmfs or add an extra option to hooks.c _similar_ to
>   fscontext but without the bit that says "stop if this filesystem
>   supports xattrs".
>
> - modify /etc/init.d/udev to then mount /dev with the default context
>   of device_t which whill FAIL if you DO NOT patch hooks.c as above:
>
>    mount -n -o
>	   fscontext=system_u:object_r:device_t,size=$tmpfs_size,mode=0755
>	   -t tmpfs none /dev
>
> - add in an equivalent of my extra post-udev-and-hotplug duplicate of
>   /etc/init.d/modutils that will load things like nvidia, ppp_generic
>   and stuff that are not yet fully 2.6-compliant drivers (i.e. they
>   don't grok /sys and consequently don't generate hotplug events) .
>
>   i assume that rawhide, given that it is using udev already, is
>   perfectly capable of doing a proper and far superior job to what
>   i have hacked up.
>
> - run a restorecon on ALL DEVICE NODES CREATED PRIOR TO /etc/init.d/udev
>   RUNNING.
>
>   i got bored of doing this regularly and manually and so wrote a
>   small script (/sbin/restoredevicefiles) which does this for me.
>   badly.  it uses ls (really must use commands NOT from /usr and must
>   use commands that DO NOT a require /dev/null or access to /dev/fd/*)
>
>   i believe i had to copy cut from /usr/bin/cut to /bin/cut (!!) hey
>   there are probably people out there who could do this as c-code
>   or with sed or something more appropriate, to be honest i haven't
>   got time to DoItRight(tm) so the ItWorksForMe(tm) approach is fine
>   for me until _someone else_ does the DoItRight(tm) approach.
>
> - udev, udevd _and_ udevsend (_why_ is udev split into three separate
>   programs??????) _all_ need to be hacked up to run setfiles -q -s on a
>   pipe which udev(d?) will communicate the name of the inode to.
>
>   russell advised me that using popen would be suitable for this:
>   however i am not sure whether it should be put in udev or in
>   udevd and i haven't the TimeRightNow(tm) to focus on
>   MakingItNice(tm)
>
>   alternatively, a patch (also attached) to add selinux "restorecon"
>   stuff to udevsend is included which, although it still has a 1/4
>   second delay per inode added, at least works.
>
>   patch is against udev-0.030.  udev-0.030 has had the
>   /etc/udev.d/default/selinux script removed which is a complete pain
>   but hey, if linux-hotplug-devel say it don't work, it don't work.
>
>
> it's taken me about three maybe four weeks to get this hacked up to
> a working / reasonably acceptable (for me at least) point.
>
> i'm assuming that you would like the kernel patches: if you would like
> me to place a copy of my hacked-up policy files at hands.com/~lkcl/selinux
> please let me know because they are not very pretty but will save you a
> lot of time: because i don't know any better it has taken me somewhere
> in excess of 100 reboots to get a working udev-tmpfs-enabled policy
> plus initscripts hacks.
>
> if someone can inform me of the appropriate cvs-based diff
> command that will allow me to include fs/ramfs/xattr.c
> and fs/ramfs/xattr-security.c in the patch i would be most
> grateful, otherwise people will just have to manually blat
> those two files (attached) into the appropriate locations.
>
> i'd _really_ appreciate it if people _could_ say "hey, yes, we
> really need tmpfs-enabled udev in fc" because then i wouldn't
> have so much crap hanging around on my debian/selinux system:
> i'd far rather it had already been done and i could have
> copied or relied on the work of more experienced individuals.
>
> l.
>
>  
>
>------------------------------------------------------------------------
>
>Index: fs/Kconfig
>===================================================================
>RCS file: /cvsroot/selinux/nsa/linux-2.6/fs/Kconfig,v
>retrieving revision 1.8
>diff -u -u -r1.8 Kconfig
>--- fs/Kconfig	18 Jun 2004 20:37:21 -0000	1.8
>+++ fs/Kconfig	22 Aug 2004 14:06:10 -0000
>@@ -925,6 +925,27 @@
> 
> 	  See <file:Documentation/filesystems/tmpfs.txt> for details.
> 
>+config TMPFS_FS_XATTR
>+	bool "tmpfs Extended Attributes"
>+	help
>+	  Extended attributes are name:value pairs associated with inodes by
>+	  the kernel or by users (see the attr(5) manual page, or visit
>+	  <http://acl.bestbits.at/> for details).
>+
>+	  If unsure, say N.
>+
>+config TMPFS_FS_SECURITY
>+	bool "tmpfs Security Labels"
>+	depends on TMPFS_FS_XATTR
>+	help
>+	  Security labels support alternative access control models
>+	  implemented by security modules like SELinux.  This option
>+	  enables an extended attribute handler for file security
>+	  labels in the tmpfs filesystem.
>+
>+	  If you are not using a security module that requires using
>+	  extended attributes for file security labels, say N.
>+
> config HUGETLBFS
> 	bool "HugeTLB file system support"
> 	depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || X86_64 || BROKEN
>Index: fs/ramfs/Makefile
>===================================================================
>RCS file: /cvsroot/selinux/nsa/linux-2.6/fs/ramfs/Makefile,v
>retrieving revision 1.1.1.1
>diff -u -u -r1.1.1.1 Makefile
>--- fs/ramfs/Makefile	14 Aug 2003 12:08:40 -0000	1.1.1.1
>+++ fs/ramfs/Makefile	22 Aug 2004 14:06:10 -0000
>@@ -5,3 +5,6 @@
> obj-$(CONFIG_RAMFS) += ramfs.o
> 
> ramfs-objs := inode.o
>+ramfs-$(CONFIG_RAMFS_FS_XATTR)    += xattr.o
>+ramfs-$(CONFIG_RAMFS_FS_SECURITY) += xattr_security.o
>+
>Index: fs/ramfs/inode.c
>===================================================================
>RCS file: /cvsroot/selinux/nsa/linux-2.6/fs/ramfs/inode.c,v
>retrieving revision 1.1.1.4
>diff -u -u -r1.1.1.4 inode.c
>--- fs/ramfs/inode.c	18 Jun 2004 19:30:21 -0000	1.1.1.4
>+++ fs/ramfs/inode.c	22 Aug 2004 14:06:11 -0000
>@@ -31,6 +31,7 @@
> #include <linux/string.h>
> #include <linux/smp_lock.h>
> #include <linux/backing-dev.h>
>+#include "xattr.h"
> 
> #include <asm/uaccess.h>
> 
>@@ -157,6 +158,10 @@
> 
> static struct inode_operations ramfs_file_inode_operations = {
> 	.getattr	= simple_getattr,
>+	.setxattr   = ramfs_setxattr,
>+	.getxattr   = ramfs_getxattr,
>+	.listxattr  = ramfs_listxattr,
>+	.removexattr    = ramfs_removexattr,
> };
> 
> static struct inode_operations ramfs_dir_inode_operations = {
>@@ -169,6 +174,10 @@
> 	.rmdir		= simple_rmdir,
> 	.mknod		= ramfs_mknod,
> 	.rename		= simple_rename,
>+	.setxattr   = ramfs_setxattr,
>+	.getxattr   = ramfs_getxattr,
>+	.listxattr  = ramfs_listxattr,
>+	.removexattr    = ramfs_removexattr,
> };
> 
> static struct super_operations ramfs_ops = {
>@@ -224,12 +233,17 @@
> 
> static int __init init_ramfs_fs(void)
> {
>+	int err = init_ramfs_xattr();
>+	if (err)
>+		return err;
>+
> 	return register_filesystem(&ramfs_fs_type);
> }
> 
> static void __exit exit_ramfs_fs(void)
> {
> 	unregister_filesystem(&ramfs_fs_type);
>+	exit_ramfs_xattr();
> }
> 
> module_init(init_ramfs_fs)
>Index: mm/Makefile
>===================================================================
>RCS file: /cvsroot/selinux/nsa/linux-2.6/mm/Makefile,v
>retrieving revision 1.1.1.4
>diff -u -u -r1.1.1.4 Makefile
>--- mm/Makefile	18 Jun 2004 19:31:02 -0000	1.1.1.4
>+++ mm/Makefile	22 Aug 2004 14:06:12 -0000
>@@ -15,3 +15,6 @@
> obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o
> obj-$(CONFIG_HUGETLBFS)	+= hugetlb.o
> obj-$(CONFIG_NUMA) 	+= mempolicy.o
>+
>+obj-$(CONFIG_TMPFS_FS_XATTR)    += xattr.o
>+obj-$(CONFIG_TMPFS_FS_SECURITY) += xattr_security.o
>Index: mm/shmem.c
>===================================================================
>RCS file: /cvsroot/selinux/nsa/linux-2.6/mm/shmem.c,v
>retrieving revision 1.1.1.8
>diff -u -u -r1.1.1.8 shmem.c
>--- mm/shmem.c	18 Jun 2004 19:31:03 -0000	1.1.1.8
>+++ mm/shmem.c	22 Aug 2004 14:06:12 -0000
>@@ -44,6 +44,8 @@
> #include <asm/div64.h>
> #include <asm/pgtable.h>
> 
>+#include "xattr.h"
>+
> /* This magic number is used in glibc for posix shared memory */
> #define TMPFS_MAGIC	0x01021994
> 
>@@ -168,6 +170,8 @@
> static struct file_operations shmem_file_operations;
> static struct inode_operations shmem_inode_operations;
> static struct inode_operations shmem_dir_inode_operations;
>+static struct inode_operations shmfs_special_inode_operations;
>+static struct inode_operations shmem_symlink_inode_operations;
> static struct vm_operations_struct shmem_vm_ops;
> 
> static struct backing_dev_info shmem_backing_dev_info = {
>@@ -1212,6 +1216,7 @@
>  		mpol_shared_policy_init(&info->policy);
> 		switch (mode & S_IFMT) {
> 		default:
>+			inode->i_op = &shmfs_special_inode_operations;
> 			init_special_inode(inode, mode, dev);
> 			break;
> 		case S_IFREG:
>@@ -1229,6 +1234,7 @@
> 			inode->i_fop = &simple_dir_operations;
> 			break;
> 		case S_IFLNK:
>+			inode->i_op = &shmem_symlink_inode_operations;
> 			break;
> 		}
> 	}
>@@ -1261,7 +1267,6 @@
> 
> #ifdef CONFIG_TMPFS
> 
>-static struct inode_operations shmem_symlink_inode_operations;
> static struct inode_operations shmem_symlink_inline_operations;
> 
> /*
>@@ -1715,12 +1720,33 @@
> static struct inode_operations shmem_symlink_inline_operations = {
> 	.readlink	= shmem_readlink_inline,
> 	.follow_link	= shmem_follow_link_inline,
>+#ifdef CONFIG_TMPFS
>+	.setxattr   = shmfs_setxattr,
>+	.getxattr   = shmfs_getxattr,
>+	.listxattr  = shmfs_listxattr,
>+	.removexattr    = shmfs_removexattr,
>+#endif
>+};
>+
>+static struct inode_operations shmfs_special_inode_operations = {
>+#ifdef CONFIG_TMPFS
>+	.setxattr   = shmfs_setxattr,
>+	.getxattr   = shmfs_getxattr,
>+	.listxattr  = shmfs_listxattr,
>+	.removexattr    = shmfs_removexattr,
>+#endif
> };
> 
> static struct inode_operations shmem_symlink_inode_operations = {
> 	.truncate	= shmem_truncate,
> 	.readlink	= shmem_readlink,
> 	.follow_link	= shmem_follow_link,
>+#ifdef CONFIG_TMPFS
>+	.setxattr   = shmfs_setxattr,
>+	.getxattr   = shmfs_getxattr,
>+	.listxattr  = shmfs_listxattr,
>+	.removexattr    = shmfs_removexattr,
>+#endif
> };
> 
> static int shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid, unsigned long *blocks, unsigned long *inodes)
>@@ -1939,6 +1965,12 @@
> static struct inode_operations shmem_inode_operations = {
> 	.truncate	= shmem_truncate,
> 	.setattr	= shmem_notify_change,
>+#ifdef CONFIG_TMPFS
>+	.setxattr   = shmfs_setxattr,
>+	.getxattr   = shmfs_getxattr,
>+	.listxattr  = shmfs_listxattr,
>+	.removexattr    = shmfs_removexattr,
>+#endif
> };
> 
> static struct inode_operations shmem_dir_inode_operations = {
>@@ -1952,6 +1984,10 @@
> 	.rmdir		= shmem_rmdir,
> 	.mknod		= shmem_mknod,
> 	.rename		= shmem_rename,
>+	.setxattr   = shmfs_setxattr,
>+	.getxattr   = shmfs_getxattr,
>+	.listxattr  = shmfs_listxattr,
>+	.removexattr    = shmfs_removexattr,
> #endif
> };
> 
>@@ -1993,6 +2029,9 @@
> static int __init init_tmpfs(void)
> {
> 	int error;
>+	int err = init_shmfs_xattr();
>+	if (err)
>+		return err;
> 
> 	error = init_inodecache();
> 	if (error)
>Index: security/selinux/hooks.c
>===================================================================
>RCS file: /cvsroot/selinux/nsa/linux-2.6/security/selinux/hooks.c,v
>retrieving revision 1.15
>diff -u -u -r1.15 hooks.c
>--- security/selinux/hooks.c	27 Jul 2004 17:43:11 -0000	1.15
>+++ security/selinux/hooks.c	22 Aug 2004 14:06:13 -0000
>@@ -385,6 +385,14 @@
> 				break;
> 
> 			case Opt_fscontext:
>+				/* lkcl: allow fscontext on file systems with xattr
>+				 *       in order to be able to mount an xattr-enabled tmpfs
>+				 *       on /dev with a different fscontext.
>+				 *       reason: shmfs and tmpfs are mapped to two types
>+				 *       but we need a third (e.g. udevfs_t) in order to
>+				 *       not interfere with / have-to-add-to either tmp_t
>+				 *       or shmfs_t
>+				 *
> 				if (sbsec->behavior != SECURITY_FS_USE_XATTR) {
> 					rc = -EINVAL;
> 					printk(KERN_WARNING "SELinux:  "
>@@ -392,6 +400,7 @@
> 					       " this filesystem type\n");
> 					goto out_free;
> 				}
>+				*/
> 				if (seen & (Opt_context|Opt_fscontext)) {
> 					rc = -EINVAL;
> 					printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
>  
>
>------------------------------------------------------------------------
>
>Index: security/selinux/hooks.c
>===================================================================
>RCS file: /cvsroot/selinux/nsa/linux-2.6/security/selinux/hooks.c,v
>retrieving revision 1.15
>diff -u -u -r1.15 hooks.c
>--- security/selinux/hooks.c	27 Jul 2004 17:43:11 -0000	1.15
>+++ security/selinux/hooks.c	22 Aug 2004 14:01:46 -0000
>@@ -385,6 +385,14 @@
> 				break;
> 
> 			case Opt_fscontext:
>+				/* lkcl: allow fscontext on file systems with xattr
>+				 *       in order to be able to mount an xattr-enabled tmpfs
>+				 *       on /dev with a different fscontext.
>+				 *       reason: shmfs and tmpfs are mapped to two types
>+				 *       but we need a third (e.g. udevfs_t) in order to
>+				 *       not interfere with / have-to-add-to either tmp_t
>+				 *       or shmfs_t
>+				 *
> 				if (sbsec->behavior != SECURITY_FS_USE_XATTR) {
> 					rc = -EINVAL;
> 					printk(KERN_WARNING "SELinux:  "
>@@ -392,6 +400,7 @@
> 					       " this filesystem type\n");
> 					goto out_free;
> 				}
>+				*/
> 				if (seen & (Opt_context|Opt_fscontext)) {
> 					rc = -EINVAL;
> 					printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
>  
>
>------------------------------------------------------------------------
>
>/*
>  File: fs/ramfs/xattr.c
> 
>  Derived from fs/ext3/xattr.c, changed in the following ways:
>      drop everything related to persistent storage of EAs
>      pass dentry rather than inode to internal methods
>      only presently define a handler for security modules
>*/
>
>#include <linux/init.h>
>#include <linux/fs.h>
>#include <linux/slab.h>
>#include <linux/string.h>
>#include <asm/semaphore.h>
>#include "xattr.h"
>
>static struct ramfs_xattr_handler *ramfs_xattr_handlers[RAMFS_XATTR_INDEX_MAX];
>static rwlock_t ramfs_handler_lock = RW_LOCK_UNLOCKED;
>
>int
>ramfs_xattr_register(int name_index, struct ramfs_xattr_handler *handler)
>{
>	int error = -EINVAL;
>
>	if (name_index > 0 && name_index <= RAMFS_XATTR_INDEX_MAX) {
>		write_lock(&ramfs_handler_lock);
>		if (!ramfs_xattr_handlers[name_index-1]) {
>			ramfs_xattr_handlers[name_index-1] = handler;
>			error = 0;
>		}
>		write_unlock(&ramfs_handler_lock);
>	}
>	return error;
>}
>
>void
>ramfs_xattr_unregister(int name_index, struct ramfs_xattr_handler *handler)
>{
>	if (name_index > 0 || name_index <= RAMFS_XATTR_INDEX_MAX) {
>		write_lock(&ramfs_handler_lock);
>		ramfs_xattr_handlers[name_index-1] = NULL;
>		write_unlock(&ramfs_handler_lock);
>	}
>}
>
>static inline const char *
>strcmp_prefix(const char *a, const char *a_prefix)
>{
>	while (*a_prefix && *a == *a_prefix) {
>		a++;
>		a_prefix++;
>	}
>	return *a_prefix ? NULL : a;
>}
>
>/*
> * Decode the extended attribute name, and translate it into
> * the name_index and name suffix.
> */
>static inline struct ramfs_xattr_handler *
>ramfs_xattr_resolve_name(const char **name)
>{
>	struct ramfs_xattr_handler *handler = NULL;
>	int i;
>
>	if (!*name)
>		return NULL;
>	read_lock(&ramfs_handler_lock);
>	for (i=0; i<RAMFS_XATTR_INDEX_MAX; i++) {
>		if (ramfs_xattr_handlers[i]) {
>			const char *n = strcmp_prefix(*name,
>				ramfs_xattr_handlers[i]->prefix);
>			if (n) {
>				handler = ramfs_xattr_handlers[i];
>				*name = n;
>				break;
>			}
>		}
>	}
>	read_unlock(&ramfs_handler_lock);
>	return handler;
>}
>
>static inline struct ramfs_xattr_handler *
>ramfs_xattr_handler(int name_index)
>{
>	struct ramfs_xattr_handler *handler = NULL;
>	if (name_index > 0 && name_index <= RAMFS_XATTR_INDEX_MAX) {
>		read_lock(&ramfs_handler_lock);
>		handler = ramfs_xattr_handlers[name_index-1];
>		read_unlock(&ramfs_handler_lock);
>	}
>	return handler;
>}
>
>/*
> * Inode operation getxattr()
> *
> * dentry->d_inode->i_sem down
> */
>ssize_t
>ramfs_getxattr(struct dentry *dentry, const char *name,
>	      void *buffer, size_t size)
>{
>	struct ramfs_xattr_handler *handler;
>
>	handler = ramfs_xattr_resolve_name(&name);
>	if (!handler)
>		return -EOPNOTSUPP;
>	return handler->get(dentry, name, buffer, size);
>}
>
>/*
> * Inode operation listxattr()
> *
> * dentry->d_inode->i_sem down
> */
>ssize_t
>ramfs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
>{
>	struct ramfs_xattr_handler *handler = NULL;
>	int i, error = 0;
>	unsigned int size = 0;
>	char *buf;
>
>	read_lock(&ramfs_handler_lock);
>
>	for (i=0; i<RAMFS_XATTR_INDEX_MAX; i++) {
>		handler = ramfs_xattr_handlers[i];
>		if (handler)
>			size += handler->list(dentry, NULL);
>	}
>
>	if (!buffer) {
>		error = size;
>		goto out;
>	} else {
>		error = -ERANGE;
>		if (size > buffer_size)
>			goto out;
>	}
>
>	buf = buffer;
>	for (i=0; i<RAMFS_XATTR_INDEX_MAX; i++) {
>		handler = ramfs_xattr_handlers[i];
>		if (handler)
>			buf += handler->list(dentry, buf);
>	}
>	error = size;
>
>out:
>	read_unlock(&ramfs_handler_lock);
>	return size;
>}
>
>/*
> * Inode operation setxattr()
> *
> * dentry->d_inode->i_sem down
> */
>int
>ramfs_setxattr(struct dentry *dentry, const char *name,
>	      const void *value, size_t size, int flags)
>{
>	struct ramfs_xattr_handler *handler;
>
>	if (size == 0)
>		value = "";  /* empty EA, do not remove */
>	handler = ramfs_xattr_resolve_name(&name);
>	if (!handler)
>		return -EOPNOTSUPP;
>	return handler->set(dentry, name, value, size, flags);
>}
>
>/*
> * Inode operation removexattr()
> *
> * dentry->d_inode->i_sem down
> */
>int
>ramfs_removexattr(struct dentry *dentry, const char *name)
>{
>	struct ramfs_xattr_handler *handler;
>
>	handler = ramfs_xattr_resolve_name(&name);
>	if (!handler)
>		return -EOPNOTSUPP;
>	return handler->set(dentry, name, NULL, 0, XATTR_REPLACE);
>}
>
>int __init
>init_ramfs_xattr(void)
>{
>#ifdef CONFIG_RAMFS_FS_SECURITY	
>	int	err;
>
>	err = ramfs_xattr_register(RAMFS_XATTR_INDEX_SECURITY,
>				    &ramfs_xattr_security_handler);
>	if (err)
>		return err;
>#endif
>
>	return 0;
>}
>
>void
>exit_ramfs_xattr(void)
>{
>#ifdef CONFIG_RAMFS_FS_SECURITY	
>	ramfs_xattr_unregister(RAMFS_XATTR_INDEX_SECURITY,
>				&ramfs_xattr_security_handler);
>#endif
>
>}
>  
>
>------------------------------------------------------------------------
>
>/*
> * File: fs/ramfs/xattr_security.c
> */
>
>#include <linux/module.h>
>#include <linux/string.h>
>#include <linux/fs.h>
>#include <linux/security.h>
>#include "xattr.h"
>
>static size_t
>ramfs_xattr_security_list(struct dentry *dentry, char *buffer)
>{
>	return security_inode_listsecurity(dentry, buffer);
>}
>
>static int
>ramfs_xattr_security_get(struct dentry *dentry, const char *name,
>			  void *buffer, size_t size)
>{
>	if (strcmp(name, "") == 0)
>		return -EINVAL;
>	return security_inode_getsecurity(dentry, name, buffer, size);
>}
>
>static int
>ramfs_xattr_security_set(struct dentry *dentry, const char *name,
>			  const void *value, size_t size, int flags)
>{
>	if (strcmp(name, "") == 0)
>		return -EINVAL;
>	return security_inode_setsecurity(dentry, name, value, size, flags);
>}
>
>struct ramfs_xattr_handler ramfs_xattr_security_handler = {
>	.prefix	= XATTR_SECURITY_PREFIX,
>	.list	= ramfs_xattr_security_list,
>	.get	= ramfs_xattr_security_get,
>	.set	= ramfs_xattr_security_set,
>};
>  
>
>------------------------------------------------------------------------
>
>#!/bin/sh
>#
># lkcl 2004aug08
>#
># restore contexts on anything in /dev which has the default device_t
># file context.
>#
># some things are meant to have device_t: hey, we set them too, makes
># no odds.
># 
># we pass all of the devs to restorecon on one line because restorecon
># caches the lookups of the filecontexts: doing a restorecon one at a
># time takes 1/4 sec per device/dir/symlink...
>
>devs=''
>#for x in `ls -altrZ /dev/ | grep -v initctl | grep device_t | grep -v "_device_t" | cut -c64-`; do
>for x in `ls -altrZ /dev/ | grep device_t | grep -v "_device_t" | cut -c64-`; do
>	echo $x
>	devs="$devs /dev/$x"
>done;
>echo $devs
>/sbin/restorecon $devs
>  
>
>------------------------------------------------------------------------
>
>--- udev-add.c.orig	2004-07-09 18:59:09.000000000 +0100
>+++ udev-add.c	2004-08-03 16:21:59.000000000 +0100
>@@ -50,6 +50,10 @@
> 
> #define LOCAL_USER "$local"
> 
>+#ifdef WITH_SELINUX
>+#include <selinux/selinux.h>
>+#endif
>+
> /* 
>  * Right now the major/minor of a device is stored in a file called
>  * "dev" in sysfs.
>@@ -92,7 +96,31 @@
> 			break;
> 		*pos = 0x00;
> 		if (stat(p, &stats)) {
>+#ifdef WITH_SELINUX
>+			int seretval = 0;
>+			security_context_t scontext;
>+		   if (is_selinux_enabled() > 0)
>+		   {
>+				seretval = matchpathcon(p, S_IFDIR, &scontext);
>+				if (seretval < 0) {
>+					dbg("matchpathcon(%s) failed\n", p);
>+				} else {
>+					seretval=setfscreatecon(scontext);
>+					if (seretval < 0)
>+						dbg("setfiles %s failed with error '%s'",
>+					p, strerror(errno));
>+				}
>+			}
>+#endif
> 			retval = mkdir(p, 0755);
>+#ifdef WITH_SELINUX
>+			if (is_selinux_enabled() > 0)
>+			{
>+			   /* after mkdir, free the context */
>+				freecon(scontext);
>+			}
>+#endif
>+									
> 			if (retval != 0) {
> 				dbg("mkdir(%s) failed with error '%s'",
> 				    p, strerror(errno));
>@@ -109,6 +137,10 @@
> {
> 	struct stat stats;
> 	int retval = 0;
>+	int seretval = 0;
>+#ifdef WITH_SELINUX
>+	security_context_t scontext;
>+#endif
> 
> 	if (stat(file, &stats) != 0)
> 		goto create;
>@@ -117,6 +149,24 @@
> 	if (((stats.st_mode & S_IFMT) == S_IFBLK || (stats.st_mode & S_IFMT) == S_IFCHR) &&
> 	    (stats.st_rdev == makedev(major, minor))) {
> 		dbg("preserve file '%s', cause it has correct dev_t", file);
>+#ifdef WITH_SELINUX
>+		/* lkcl: maybe someone would like to do the same thing with se/linux
>+		 * security contexts (check they are the same) but hey, not me!
>+		 */
>+	   if (is_selinux_enabled() > 0)
>+	   {
>+			retval = matchpathcon(file, mode, &scontext);
>+			if (retval < 0) {
>+				dbg("matchpathcon(%s) failed\n", file);
>+			} else {
>+				retval=setfilecon(scontext, file);
>+				if (retval < 0)
>+					dbg("setfiles %s failed with error '%s'",
>+				file, strerror(errno));
>+				freecon(scontext);
>+			}
>+		}
>+#endif
> 		goto perms;
> 	}
> 
>@@ -126,6 +176,21 @@
> 		dbg("already present file '%s' unlinked", file);
> 
> create:
>+#ifdef WITH_SELINUX
>+   if (is_selinux_enabled() > 0)
>+   {
>+		seretval = matchpathcon(file, mode, &scontext);
>+		if (seretval < 0) {
>+			dbg("matchpathcon(%s) failed\n", file);
>+		} else {
>+			retval=setfscreatecon(scontext);
>+			if (retval < 0)
>+				dbg("setfiles %s failed with error '%s'",
>+			file, strerror(errno));
>+		}
>+	}
>+#endif
>+						    
> 	retval = mknod(file, mode, makedev(major, minor));
> 	if (retval != 0) {
> 		dbg("mknod(%s, %#o, %u, %u) failed with error '%s'",
>@@ -133,6 +198,15 @@
> 		goto exit;
> 	}
> 
>+#ifdef WITH_SELINUX
>+   if (is_selinux_enabled() > 0)
>+   {
>+	   /* after mknod, free the context */
>+		if (seretval == 0)
>+			freecon(scontext);
>+	}
>+#endif
>+						    
> perms:
> 	dbg("chmod(%s, %#o)", file, mode);
> 	if (chmod(file, mode) != 0) {
>@@ -150,7 +224,11 @@
> 	}
> 
> exit:
>+#ifdef WITH_SELINUX
>+	return retval < 0 ? retval : seretval;
>+#else
> 	return retval;
>+#endif
> }
> 
> /* get the local logged in user */
>@@ -304,10 +382,36 @@
> 
> 		dbg("symlink(%s, %s)", linktarget, filename);
> 		if (!fake) {
>+#ifdef WITH_SELINUX
>+			int seretval = 0;
>+			security_context_t scontext;
>+		   if (is_selinux_enabled() > 0)
>+		   {
>+				seretval = matchpathcon(filename, S_IFLNK, &scontext);
>+				if (seretval < 0) {
>+					dbg("matchpathcon(%s) failed\n", filename);
>+				} else {
>+					seretval=setfscreatecon(scontext);
>+					if (seretval < 0)
>+						dbg("setfiles %s failed with error '%s'",
>+					filename, strerror(errno));
>+				}
>+			}
>+#endif
>+									
>+
> 			unlink(filename);
> 			if (symlink(linktarget, filename) != 0)
> 				dbg("symlink(%s, %s) failed with error '%s'",
> 				    linktarget, filename, strerror(errno));
>+#ifdef WITH_SELINUX
>+		   if (is_selinux_enabled() > 0)
>+		   {
>+			   /* after symlink, free the context */
>+				freecon(scontext);
>+			}
>+#endif
>+									
> 		}
> 	}
> 
>@@ -403,6 +507,11 @@
> 	char *pos;
> 	int retval;
> 
>+#ifdef WITH_SELINUX
>+	int seretval;
>+	security_context_t prev_scontext;
>+#endif
>+
> 	memset(&dev, 0x00, sizeof(dev));
> 
> 	dev.type = get_device_type(path, subsystem);
>@@ -438,6 +547,23 @@
> 
> 	dbg("name='%s'", dev.name);
> 
>+#ifdef WITH_SELINUX
>+	/* record the present security context, for file-creation
>+	 * restoration creation purposes.
>+	 *
>+	 * we're going to assume that between now and the time that
>+	 * this context is restored that the only filecreation of any
>+	 * kind to occur will be mknod, symlink and mkdirs.
>+	 */
>+
>+	if (is_selinux_enabled() > 0)
>+	{
>+		seretval = getfscreatecon(&prev_scontext);
>+		if (seretval < 0) {
>+			dbg("getfscreatecon failed\n");
>+		}
>+	}
>+#endif
> 	switch (dev.type) {
> 	case 'b':
> 	case 'c':
>@@ -474,6 +600,16 @@
> 		break;
> 	}
> 
>+#ifdef WITH_SELINUX
>+	if (is_selinux_enabled() > 0)
>+	{
>+	   /* reset the file create context to its former glory */
>+		if (seretval == 0)
>+			seretval=setfscreatecon(prev_scontext);
>+		freecon(prev_scontext);
>+	}
>+#endif
>+
> exit:
> 	sysfs_close_class_device(class_dev);
> 
>--- Makefile.orig	2004-08-02 22:23:58.000000000 +0100
>+++ Makefile	2004-08-02 22:24:01.000000000 +0100
>@@ -25,6 +25,8 @@
> # Leave this set to `false' for production use.
> DEBUG = true
> 
>+# Set this to compile with Security-Enhanced Linux support.
>+WITH_SELINUX = true
> 
> ROOT =		udev
> DAEMON =	udevd
>@@ -39,6 +41,7 @@
> LOCAL_CFG_DIR =	etc/udev
> HOTPLUG_EXEC =	$(ROOT)
> 
>+
> DESTDIR =
> 
> KERNEL_DIR = /lib/modules/${shell uname -r}/build
>@@ -172,6 +175,13 @@
> 
> CFLAGS += -I$(PWD)/libsysfs
> 
>+ifeq ($(strip $(WITH_SELINUX)),true)
>+	LIB_OBJS +=	\
>+			-lselinux
>+	CFLAGS += \
>+		-DWITH_SELINUX
>+endif
>+
> all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(STARTER)
> 	@extras="$(EXTRAS)" ; for target in $$extras ; do \
> 		echo $$target ; \
>  
>




More information about the fedora-selinux-list mailing list