public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC][PATCH 0/3] Access Control Lists for tmpfs and /dev/pts
@ 2005-02-02 16:13 Andreas Gruenbacher
  2005-02-02 16:25 ` [RFC][PATCH 3/3] Access Control Lists for /dev/pts Andreas Gruenbacher
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Andreas Gruenbacher @ 2005-02-02 16:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Chris Mason

Here is a set of three patches which implement some general
infrastructure and on top of that, acls for tmpfs and /dev/pts files.
We may want to factor out some of the current ext2 and ext3 acl code
and use the generic layer instead. Comments welcome.

Regards,
--
Andreas Gruenbacher <agruen@suse.de>
SUSE Labs, SUSE LINUX PRODUCTS GMBH


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC][PATCH 3/3] Access Control Lists for /dev/pts
  2005-02-02 16:13 [RFC][PATCH 0/3] Access Control Lists for tmpfs and /dev/pts Andreas Gruenbacher
@ 2005-02-02 16:25 ` Andreas Gruenbacher
  2005-02-02 16:25 ` [RFC][PATCH 2/3] Access Control Lists for tmpfs Andreas Gruenbacher
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Andreas Gruenbacher @ 2005-02-02 16:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Chris Mason

[-- Attachment #1: devpts-acl.diff --]
[-- Type: text/plain, Size: 7416 bytes --]

/dev/pts is somewhat special: there are no directories, and so we
don't need default acls.

Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

Index: linux-2.6.11-rc2-mm2/fs/devpts/inode.c
===================================================================
--- linux-2.6.11-rc2-mm2.orig/fs/devpts/inode.c
+++ linux-2.6.11-rc2-mm2/fs/devpts/inode.c
@@ -19,15 +19,43 @@
 #include <linux/tty.h>
 #include <linux/devpts_fs.h>
 #include <linux/xattr.h>
+#include <linux/generic_acl.h>
 
 #define DEVPTS_SUPER_MAGIC 0x1cd1
 
+#ifdef CONFIG_DEVPTS_POSIX_ACL
+static struct inode *
+devpts_alloc_inode(struct super_block *sb)
+{
+	struct devpts_inode_info *ei;
+	ei = kmalloc(sizeof(*ei), SLAB_KERNEL);
+	if (!ei)
+		return NULL;
+	inode_init_once(&ei->vfs_inode);
+	ei->i_acl = NULL;
+	return &ei->vfs_inode;
+}
+
+static void
+devpts_destroy_inode(struct inode *inode)
+{
+	struct devpts_inode_info *ei = DEVPTS_I(inode);
+	if (ei->i_acl)
+		posix_acl_release(ei->i_acl);
+	kfree(ei);
+}
+#endif  /* CONFIG_DEVPTS_POSIX_ACL */
+
 extern struct xattr_handler devpts_xattr_security_handler;
+extern struct xattr_handler devpts_xattr_acl_access_handler;
 
 static struct xattr_handler *devpts_xattr_handlers[] = {
 #ifdef CONFIG_DEVPTS_FS_SECURITY
 	&devpts_xattr_security_handler,
 #endif
+#ifdef CONFIG_DEVPTS_POSIX_ACL
+	&devpts_xattr_acl_access_handler,
+#endif
 	NULL
 };
 
@@ -38,6 +66,10 @@ static struct inode_operations devpts_fi
 	.listxattr	= generic_listxattr,
 	.removexattr	= generic_removexattr,
 #endif
+#ifdef CONFIG_DEVPTS_POSIX_ACL
+	.setattr	= devpts_setattr,
+	.permission	= devpts_permission,
+#endif
 };
 
 static struct vfsmount *devpts_mnt;
@@ -89,6 +121,10 @@ static int devpts_remount(struct super_b
 }
 
 static struct super_operations devpts_sops = {
+#ifdef CONFIG_DEVPTS_POSIX_ACL
+	.alloc_inode    = devpts_alloc_inode,
+	.destroy_inode	= devpts_destroy_inode,
+#endif
 	.statfs		= simple_statfs,
 	.remount_fs	= devpts_remount,
 };
@@ -117,6 +153,9 @@ devpts_fill_super(struct super_block *s,
 	inode->i_op = &simple_dir_inode_operations;
 	inode->i_fop = &simple_dir_operations;
 	inode->i_nlink = 2;
+#ifdef CONFIG_TMPFS_POSIX_ACL
+	s->s_flags |= MS_POSIXACL;
+#endif
 
 	devpts_root = s->s_root = d_alloc_root(inode);
 	if (s->s_root)
Index: linux-2.6.11-rc2-mm2/fs/devpts/Makefile
===================================================================
--- linux-2.6.11-rc2-mm2.orig/fs/devpts/Makefile
+++ linux-2.6.11-rc2-mm2/fs/devpts/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_UNIX98_PTYS)		+= devpts.o
 
 devpts-$(CONFIG_UNIX98_PTYS)		:= inode.o
 devpts-$(CONFIG_DEVPTS_FS_SECURITY)	+= xattr_security.o
+devpts-$(CONFIG_DEVPTS_POSIX_ACL)	+= acl.o
Index: linux-2.6.11-rc2-mm2/include/linux/devpts_fs.h
===================================================================
--- linux-2.6.11-rc2-mm2.orig/include/linux/devpts_fs.h
+++ linux-2.6.11-rc2-mm2/include/linux/devpts_fs.h
@@ -17,6 +17,23 @@
 
 #ifdef CONFIG_UNIX98_PTYS
 
+#ifdef CONFIG_DEVPTS_POSIX_ACL
+struct devpts_inode_info {
+	struct posix_acl	*i_acl;
+	struct inode		vfs_inode;
+};
+
+static inline struct devpts_inode_info *DEVPTS_I(struct inode *inode)
+{
+	return container_of(inode, struct devpts_inode_info, vfs_inode);
+}
+
+/* acl.c */
+int devpts_setattr(struct dentry *, struct iattr *);
+int devpts_permission(struct inode *, int, struct nameidata *);
+#endif  /* CONFIG_DEVPTS_POSIX_ACL */
+
+/* inode.c */
 int devpts_pty_new(struct tty_struct *tty);      /* mknod in devpts */
 struct tty_struct *devpts_get_tty(int number);	 /* get tty structure */
 void devpts_pty_kill(int number);		 /* unlink */
Index: linux-2.6.11-rc2-mm2/fs/Kconfig
===================================================================
--- linux-2.6.11-rc2-mm2.orig/fs/Kconfig
+++ linux-2.6.11-rc2-mm2/fs/Kconfig
@@ -850,6 +850,19 @@ config DEVPTS_FS_XATTR
 
 	  If unsure, say N.
 
+config DEVPTS_POSIX_ACL
+	bool "/dev/pts POSIX Access Control Lists"
+	depends on DEVPTS_FS_XATTR
+	select GENERIC_ACL
+	help
+	  POSIX Access Control Lists (ACLs) support permissions for users and
+	  groups beyond the owner/group/world scheme.
+
+	  To learn more about Access Control Lists, visit the POSIX ACLs for
+	  Linux website <http://acl.bestbits.at/>.
+
+	  If you don't know what Access Control Lists are, say N.
+
 config DEVPTS_FS_SECURITY
 	bool "/dev/pts Security Labels"
 	depends on DEVPTS_FS_XATTR
Index: linux-2.6.11-rc2-mm2/fs/devpts/acl.c
===================================================================
--- /dev/null
+++ linux-2.6.11-rc2-mm2/fs/devpts/acl.c
@@ -0,0 +1,112 @@
+/*
+ * fs/devpts/acl.c
+ *
+ * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
+ *
+ * This file is released under the GPL.
+ */
+
+#include <linux/fs.h>
+#include <linux/tty.h>
+#include <linux/devpts_fs.h>
+#include <linux/xattr.h>
+#include <linux/generic_acl.h>
+
+static struct posix_acl *
+devpts_get_acl(struct inode *inode, int type)
+{
+	struct posix_acl *acl = NULL;
+
+	spin_lock(&inode->i_lock);
+	if (type == ACL_TYPE_ACCESS)
+		acl = posix_acl_dup(DEVPTS_I(inode)->i_acl);
+	spin_unlock(&inode->i_lock);
+
+	return acl;
+}
+
+static void
+devpts_set_acl(struct inode *inode, int type, struct posix_acl *acl)
+{
+	spin_lock(&inode->i_lock);
+	if (type == ACL_TYPE_ACCESS) {
+		if (DEVPTS_I(inode)->i_acl)
+			posix_acl_release(DEVPTS_I(inode)->i_acl);
+		DEVPTS_I(inode)->i_acl = posix_acl_dup(acl);
+	}
+	spin_unlock(&inode->i_lock);
+}
+
+struct generic_acl_operations devpts_acl_ops = {
+	.getacl = devpts_get_acl,
+	.setacl = devpts_set_acl,
+};
+
+static size_t
+devpts_list_acl_access(struct inode *inode, char *list, size_t list_size,
+		       const char *name, size_t name_len)
+{
+	return generic_acl_list(inode, &devpts_acl_ops, ACL_TYPE_ACCESS,
+				list, list_size);
+}
+
+static int
+devpts_get_acl_access(struct inode *inode, const char *name, void *buffer,
+		      size_t size)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return generic_acl_get(inode, &devpts_acl_ops, ACL_TYPE_ACCESS, buffer,
+			       size);
+}
+
+static int
+devpts_set_acl_access(struct inode *inode, const char *name, const void *value,
+		      size_t size, int flags)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return generic_acl_set(inode, &devpts_acl_ops, ACL_TYPE_ACCESS, value,
+			       size);
+}
+
+struct xattr_handler devpts_xattr_acl_access_handler = {
+	.prefix = XATTR_NAME_ACL_ACCESS,
+	.list   = devpts_list_acl_access,
+	.get    = devpts_get_acl_access,
+	.set    = devpts_set_acl_access,
+};
+
+int
+devpts_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+	struct inode *inode = dentry->d_inode;
+	int error;
+
+	error = inode_change_ok(inode, iattr);
+	if (error)
+		return error;
+	error = inode_setattr(inode, iattr);
+	if (!error && (iattr->ia_valid & ATTR_MODE))
+		error = generic_acl_chmod(inode, &devpts_acl_ops);
+	return error;
+}
+
+static int
+devpts_check_acl(struct inode *inode, int mask)
+{
+        struct posix_acl *acl = devpts_get_acl(inode, ACL_TYPE_ACCESS);
+
+        if (acl) {
+                int error = posix_acl_permission(inode, acl, mask);
+                posix_acl_release(acl);
+                return error;
+        }
+        return -EAGAIN;
+}
+
+int
+devpts_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+        return generic_permission(inode, mask, devpts_check_acl);
+}

--
Andreas Gruenbacher <agruen@suse.de>
SUSE Labs, SUSE LINUX PRODUCTS GMBH


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC][PATCH 2/3] Access Control Lists for tmpfs
  2005-02-02 16:13 [RFC][PATCH 0/3] Access Control Lists for tmpfs and /dev/pts Andreas Gruenbacher
  2005-02-02 16:25 ` [RFC][PATCH 3/3] Access Control Lists for /dev/pts Andreas Gruenbacher
@ 2005-02-02 16:25 ` Andreas Gruenbacher
  2005-02-02 16:29 ` [RFC][PATCH 1/3] Generic infrastructure for acls Andreas Gruenbacher
  2005-02-02 16:55 ` [RFC][PATCH 0/3] Access Control Lists for tmpfs and /dev/pts Christoph Hellwig
  3 siblings, 0 replies; 7+ messages in thread
From: Andreas Gruenbacher @ 2005-02-02 16:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Chris Mason

[-- Attachment #1: tmpfs-acl.diff --]
[-- Type: text/plain, Size: 9915 bytes --]

Add access control lists for tmpfs. There is more code in tmpfs itself
than in the generic acl layer, but at least the acl handling
complexities are hidden from the filesystem.

Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

Index: linux-2.6.11-rc2-mm2/mm/shmem.c
===================================================================
--- linux-2.6.11-rc2-mm2.orig/mm/shmem.c
+++ linux-2.6.11-rc2-mm2/mm/shmem.c
@@ -1617,6 +1617,8 @@ static int shmem_statfs(struct super_blo
 	return 0;
 }
 
+static void shmem_destroy_inode(struct inode *inode);
+
 /*
  * File creation. Allocate an inode, and we're done..
  */
@@ -1627,6 +1629,11 @@ shmem_mknod(struct inode *dir, struct de
 	int error = -ENOSPC;
 
 	if (inode) {
+		error = shmem_acl_init(inode, dir);
+		if (error) {
+			shmem_destroy_inode(inode);
+			return error;
+		}
 		if (dir->i_mode & S_ISGID) {
 			inode->i_gid = dir->i_gid;
 			if (S_ISDIR(mode))
@@ -1993,6 +2000,9 @@ static int shmem_fill_super(struct super
 		sbinfo->free_inodes = inodes;
 	}
 	sb->s_xattr = shmem_xattr_handlers;
+#ifdef CONFIG_TMPFS_POSIX_ACL
+	sb->s_flags |= MS_POSIXACL;
+#endif
 #else
 	sb->s_flags |= MS_NOUSER;
 #endif
@@ -2037,6 +2047,7 @@ static void shmem_destroy_inode(struct i
 		/* only struct inode is valid if it's an inline symlink */
 		mpol_free_shared_policy(&SHMEM_I(inode)->policy);
 	}
+	shmem_acl_destroy_inode(inode);
 	kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode));
 }
 
@@ -2047,6 +2058,10 @@ static void init_once(void *foo, kmem_ca
 	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
 	    SLAB_CTOR_CONSTRUCTOR) {
 		inode_init_once(&p->vfs_inode);
+#ifdef CONFIG_TMPFS_POSIX_ACL
+		p->i_acl = NULL;
+		p->i_default_acl = NULL;
+#endif
 	}
 }
 
@@ -2095,6 +2110,8 @@ static struct inode_operations shmem_ino
 	.listxattr      = generic_listxattr,
 	.removexattr    = generic_removexattr,
 #endif
+	.setattr	= shmem_setattr,
+	.permission	= shmem_permission,
 };
 
 static struct inode_operations shmem_dir_inode_operations = {
@@ -2114,6 +2131,8 @@ static struct inode_operations shmem_dir
 	.listxattr      = generic_listxattr,
 	.removexattr    = generic_removexattr,
 #endif
+	.setattr	= shmem_setattr,
+	.permission	= shmem_permission,
 #endif
 };
 
@@ -2124,6 +2143,8 @@ static struct inode_operations shmem_spe
 	.listxattr	= generic_listxattr,
 	.removexattr	= generic_removexattr,
 #endif
+	.setattr	= shmem_setattr,
+	.permission	= shmem_permission,
 };
 
 static struct super_operations shmem_ops = {
@@ -2182,6 +2203,10 @@ static struct xattr_handler shmem_xattr_
 #ifdef CONFIG_TMPFS_XATTR
 
 static struct xattr_handler *shmem_xattr_handlers[] = {
+#ifdef CONFIG_TMPFS_POSIX_ACL
+	&shmem_xattr_acl_access_handler,
+	&shmem_xattr_acl_default_handler,
+#endif
 #ifdef CONFIG_TMPFS_SECURITY
 	&shmem_xattr_security_handler,
 #endif
Index: linux-2.6.11-rc2-mm2/include/linux/shmem_fs.h
===================================================================
--- linux-2.6.11-rc2-mm2.orig/include/linux/shmem_fs.h
+++ linux-2.6.11-rc2-mm2/include/linux/shmem_fs.h
@@ -19,6 +19,10 @@ struct shmem_inode_info {
 	swp_entry_t		i_direct[SHMEM_NR_DIRECT]; /* first blocks */
 	struct list_head	swaplist;	/* chain of maybes on swap */
 	struct inode		vfs_inode;
+#ifdef CONFIG_TMPFS_POSIX_ACL
+	struct posix_acl	*i_acl;
+	struct posix_acl	*i_default_acl;
+#endif
 };
 
 struct shmem_sb_info {
@@ -34,4 +38,25 @@ static inline struct shmem_inode_info *S
 	return container_of(inode, struct shmem_inode_info, vfs_inode);
 }
 
+#ifdef CONFIG_TMPFS_POSIX_ACL
+int shmem_setattr(struct dentry *, struct iattr *);
+int shmem_permission(struct inode *, int, struct nameidata *);
+int shmem_acl_init(struct inode *, struct inode *);
+void shmem_acl_destroy_inode(struct inode *);
+
+extern struct xattr_handler shmem_xattr_acl_access_handler;
+extern struct xattr_handler shmem_xattr_acl_default_handler;
+#else
+#define shmem_setattr NULL
+#define shmem_permission NULL
+
+static inline int shmem_acl_init(struct inode *inode, struct inode *dir)
+{
+	return 0;
+}
+void shmem_acl_destroy_inode(struct inode *inode)
+{
+}
+#endif  /* CONFIG_TMPFS_POSIX_ACL */
+
 #endif
Index: linux-2.6.11-rc2-mm2/fs/Kconfig
===================================================================
--- linux-2.6.11-rc2-mm2.orig/fs/Kconfig
+++ linux-2.6.11-rc2-mm2/fs/Kconfig
@@ -884,6 +884,19 @@ config TMPFS_XATTR
 
 	  If unsure, say N.
 
+config TMPFS_POSIX_ACL
+	bool "tmpfs POSIX Access Control Lists"
+	depends on TMPFS_XATTR
+	select GENERIC_ACL
+	help
+	  POSIX Access Control Lists (ACLs) support permissions for users and
+	  groups beyond the owner/group/world scheme.
+
+	  To learn more about Access Control Lists, visit the POSIX ACLs for
+	  Linux website <http://acl.bestbits.at/>.
+
+	  If you don't know what Access Control Lists are, say N.
+
 config TMPFS_SECURITY
 	bool "tmpfs Security Labels"
 	depends on TMPFS_XATTR
Index: linux-2.6.11-rc2-mm2/mm/shmem_acl.c
===================================================================
--- /dev/null
+++ linux-2.6.11-rc2-mm2/mm/shmem_acl.c
@@ -0,0 +1,178 @@
+/*
+ * mm/shmem_acl.c
+ *
+ * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
+ *
+ * This file is released under the GPL.
+ */
+
+#include <linux/fs.h>
+#include <linux/shmem_fs.h>
+#include <linux/xattr.h>
+#include <linux/generic_acl.h>
+
+static struct posix_acl *
+shmem_get_acl(struct inode *inode, int type)
+{
+	struct posix_acl *acl = NULL;
+
+	spin_lock(&inode->i_lock);
+	switch(type) {
+		case ACL_TYPE_ACCESS:
+			acl = posix_acl_dup(SHMEM_I(inode)->i_acl);
+			break;
+
+		case ACL_TYPE_DEFAULT:
+			acl = posix_acl_dup(SHMEM_I(inode)->i_default_acl);
+			break;
+	}
+	spin_unlock(&inode->i_lock);
+
+	return acl;
+}
+
+static void
+shmem_set_acl(struct inode *inode, int type, struct posix_acl *acl)
+{
+	spin_lock(&inode->i_lock);
+	switch(type) {
+		case ACL_TYPE_ACCESS:
+			if (SHMEM_I(inode)->i_acl)
+				posix_acl_release(SHMEM_I(inode)->i_acl);
+			SHMEM_I(inode)->i_acl = posix_acl_dup(acl);
+			break;
+			
+		case ACL_TYPE_DEFAULT:
+			if (SHMEM_I(inode)->i_default_acl)
+				posix_acl_release(SHMEM_I(inode)->i_default_acl);
+			SHMEM_I(inode)->i_default_acl = posix_acl_dup(acl);
+			break;
+	}
+	spin_unlock(&inode->i_lock);
+}
+
+struct generic_acl_operations shmem_acl_ops = {
+	.getacl = shmem_get_acl,
+	.setacl = shmem_set_acl,
+};
+
+static size_t
+shmem_list_acl_access(struct inode *inode, char *list, size_t list_size,
+		      const char *name, size_t name_len)
+{
+	return generic_acl_list(inode, &shmem_acl_ops, ACL_TYPE_ACCESS,
+				list, list_size);
+}
+
+static size_t
+shmem_list_acl_default(struct inode *inode, char *list, size_t list_size,
+		       const char *name, size_t name_len)
+{
+	return generic_acl_list(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT,
+				list, list_size);
+}
+
+static int
+shmem_get_acl_access(struct inode *inode, const char *name, void *buffer,
+		     size_t size)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return generic_acl_get(inode, &shmem_acl_ops, ACL_TYPE_ACCESS, buffer,
+			       size);
+}
+
+static int
+shmem_get_acl_default(struct inode *inode, const char *name, void *buffer,
+		      size_t size)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return generic_acl_get(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT, buffer,
+			       size);
+}
+
+static int
+shmem_set_acl_access(struct inode *inode, const char *name, const void *value,
+		     size_t size, int flags)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return generic_acl_set(inode, &shmem_acl_ops, ACL_TYPE_ACCESS, value,
+			       size);
+}
+
+static int
+shmem_set_acl_default(struct inode *inode, const char *name, const void *value,
+		      size_t size, int flags)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return generic_acl_set(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT, value,
+			       size);
+}
+
+struct xattr_handler shmem_xattr_acl_access_handler = {
+	.prefix = XATTR_NAME_ACL_ACCESS,
+	.list	= shmem_list_acl_access,
+	.get	= shmem_get_acl_access,
+	.set	= shmem_set_acl_access,
+};
+
+struct xattr_handler shmem_xattr_acl_default_handler = {
+	.prefix = XATTR_NAME_ACL_DEFAULT,
+	.list	= shmem_list_acl_default,
+	.get	= shmem_get_acl_default,
+	.set	= shmem_set_acl_default,
+};
+
+int
+shmem_acl_init(struct inode *inode, struct inode *dir)
+{
+	return generic_acl_init(inode, dir, &shmem_acl_ops);
+}
+
+void
+shmem_acl_destroy_inode(struct inode *inode)
+{
+	if (SHMEM_I(inode)->i_acl)
+		posix_acl_release(SHMEM_I(inode)->i_acl);
+	if (SHMEM_I(inode)->i_default_acl)
+		posix_acl_release(SHMEM_I(inode)->i_default_acl);
+	SHMEM_I(inode)->i_acl = NULL;
+	SHMEM_I(inode)->i_default_acl = NULL;
+}
+
+int
+shmem_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+	struct inode *inode = dentry->d_inode;
+	int error;
+	
+	error = inode_change_ok(inode, iattr);
+	if (error)
+		return error;
+	error = inode_setattr(inode, iattr);
+	if (!error && (iattr->ia_valid & ATTR_MODE))
+		error = generic_acl_chmod(inode, &shmem_acl_ops);
+	return error;
+}
+
+static int
+shmem_check_acl(struct inode *inode, int mask)
+{
+	struct posix_acl *acl = shmem_get_acl(inode, ACL_TYPE_ACCESS);
+
+	if (acl) {
+		int error = posix_acl_permission(inode, acl, mask);
+		posix_acl_release(acl);
+		return error;
+	}
+	return -EAGAIN;
+}
+
+int
+shmem_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+	return generic_permission(inode, mask, shmem_check_acl);
+}
Index: linux-2.6.11-rc2-mm2/mm/Makefile
===================================================================
--- linux-2.6.11-rc2-mm2.orig/mm/Makefile
+++ linux-2.6.11-rc2-mm2/mm/Makefile
@@ -17,4 +17,5 @@ obj-$(CONFIG_HUGETLBFS)	+= hugetlb.o
 obj-$(CONFIG_NUMA) 	+= mempolicy.o
 obj-$(CONFIG_SHMEM) += shmem.o
 obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
+obj-$(CONFIG_TMPFS_POSIX_ACL) += shmem_acl.o
 

--
Andreas Gruenbacher <agruen@suse.de>
SUSE Labs, SUSE LINUX PRODUCTS GMBH


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC][PATCH 1/3] Generic infrastructure for acls
  2005-02-02 16:13 [RFC][PATCH 0/3] Access Control Lists for tmpfs and /dev/pts Andreas Gruenbacher
  2005-02-02 16:25 ` [RFC][PATCH 3/3] Access Control Lists for /dev/pts Andreas Gruenbacher
  2005-02-02 16:25 ` [RFC][PATCH 2/3] Access Control Lists for tmpfs Andreas Gruenbacher
@ 2005-02-02 16:29 ` Andreas Gruenbacher
  2005-02-02 16:55 ` [RFC][PATCH 0/3] Access Control Lists for tmpfs and /dev/pts Christoph Hellwig
  3 siblings, 0 replies; 7+ messages in thread
From: Andreas Gruenbacher @ 2005-02-02 16:29 UTC (permalink / raw)
  To: linux-kernel; +Cc: Chris Mason

[-- Attachment #1: generic-acl.diff --]
[-- Type: text/plain, Size: 6015 bytes --]

Add some infrastructure for access control lists on in-memory
filesystems such as tmpfs and devpts. We can probably also use
this code from ext2 and ext3, but this hasn't been started, yet.

Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

Index: linux-2.6.11-rc2-mm2/fs/Kconfig
===================================================================
--- linux-2.6.11-rc2-mm2.orig/fs/Kconfig
+++ linux-2.6.11-rc2-mm2/fs/Kconfig
@@ -1809,6 +1809,10 @@ config AFS_FSCACHE
 config RXRPC
 	tristate
 
+config GENERIC_ACL
+	bool
+	select FS_POSIX_ACL
+
 endmenu
 
 menu "Partition Types"
Index: linux-2.6.11-rc2-mm2/fs/Makefile
===================================================================
--- linux-2.6.11-rc2-mm2.orig/fs/Makefile
+++ linux-2.6.11-rc2-mm2/fs/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_BINFMT_FLAT)	+= binfmt_flat
 
 obj-$(CONFIG_FS_MBCACHE)	+= mbcache.o
 obj-$(CONFIG_FS_POSIX_ACL)	+= posix_acl.o xattr_acl.o
+obj-$(CONFIG_GENERIC_ACL)	+= generic_acl.o
 obj-$(CONFIG_NFS_ACL_SUPPORT)	+= nfsacl.o
 
 obj-$(CONFIG_QUOTA)		+= dquot.o
Index: linux-2.6.11-rc2-mm2/include/linux/generic_acl.h
===================================================================
--- /dev/null
+++ linux-2.6.11-rc2-mm2/include/linux/generic_acl.h
@@ -0,0 +1,30 @@
+/*
+ * fs/generic_acl.c
+ *
+ * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef GENERIC_ACL_H
+#define GENERIC_ACL_H
+
+#include <linux/posix_acl.h>
+#include <linux/xattr_acl.h>
+
+struct generic_acl_operations {
+	struct posix_acl *(*getacl)(struct inode *, int);
+	void (*setacl)(struct inode *, int, struct posix_acl *);
+};
+
+size_t generic_acl_list(struct inode *, struct generic_acl_operations *, int,
+			char *, size_t);
+int generic_acl_get(struct inode *, struct generic_acl_operations *, int,
+		    void *, size_t);
+int generic_acl_set(struct inode *, struct generic_acl_operations *, int,
+		    const void *, size_t);
+int generic_acl_init(struct inode *, struct inode *,
+		     struct generic_acl_operations *);
+int generic_acl_chmod(struct inode *, struct generic_acl_operations *);
+
+#endif
Index: linux-2.6.11-rc2-mm2/fs/generic_acl.c
===================================================================
--- /dev/null
+++ linux-2.6.11-rc2-mm2/fs/generic_acl.c
@@ -0,0 +1,172 @@
+/*
+ * fs/generic_acl.c
+ *
+ * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
+ *
+ * This file is released under the GPL.
+ */
+
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/generic_acl.h>
+
+size_t
+generic_acl_list(struct inode *inode, struct generic_acl_operations *ops,
+		 int type, char *list, size_t list_size)
+{
+	struct posix_acl *acl;
+	const char *name;
+	size_t size;
+	
+	acl = ops->getacl(inode, type);
+	if (!acl)
+		return 0;
+	posix_acl_release(acl);
+
+	switch(type) {
+		case ACL_TYPE_ACCESS:
+			name = XATTR_NAME_ACL_ACCESS;
+			break;
+
+		case ACL_TYPE_DEFAULT:
+			name = XATTR_NAME_ACL_DEFAULT;
+			break;
+			
+		default:
+			return 0;
+	}
+	size = strlen(name) + 1;
+	if (list && size <= list_size)
+		memcpy(list, name, size);
+	return size;
+}
+
+int
+generic_acl_get(struct inode *inode, struct generic_acl_operations *ops,
+		int type, void *buffer, size_t size)
+{
+	struct posix_acl *acl;
+	int error;
+
+	acl = ops->getacl(inode, type);
+	if (!acl)
+		return -ENODATA;
+	error = posix_acl_to_xattr(acl, buffer, size);
+	posix_acl_release(acl);
+
+	return error;
+}
+
+int
+generic_acl_set(struct inode *inode, struct generic_acl_operations *ops,
+		int type, const void *value, size_t size)
+{
+	struct posix_acl *acl = NULL;
+	int error;
+
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+	if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+		return -EPERM;
+	if (value) {
+		acl = posix_acl_from_xattr(value, size);
+		if (IS_ERR(acl))
+			return PTR_ERR(acl);
+	}
+	if (acl) {
+		mode_t mode;
+
+		error = posix_acl_valid(acl);
+		if (error)
+			goto failed;
+		switch(type) {
+			case ACL_TYPE_ACCESS:
+				mode = inode->i_mode;
+				error = posix_acl_equiv_mode(acl, &mode);
+				if (error < 0)
+					goto failed;
+				inode->i_mode = mode;
+				if (error == 0) {
+					posix_acl_release(acl);
+					acl = NULL;
+				}
+				break;
+
+			case ACL_TYPE_DEFAULT:
+				if (!S_ISDIR(inode->i_mode)) {
+					error = -EINVAL;
+					goto failed;
+				}
+				break;
+		}
+	}
+	ops->setacl(inode, type, acl);
+	error = 0;
+failed:
+	posix_acl_release(acl);
+	return error;
+}
+
+int
+generic_acl_init(struct inode *inode, struct inode *dir,
+		 struct generic_acl_operations *ops)
+{
+	struct posix_acl *acl = NULL;
+	mode_t mode = inode->i_mode;
+	int error;
+
+	inode->i_mode = mode & ~current->fs->umask;
+	if (!S_ISLNK(inode->i_mode))
+		acl = ops->getacl(dir, ACL_TYPE_DEFAULT);
+	if (acl) {
+		struct posix_acl *clone;
+		
+		if (S_ISDIR(inode->i_mode)) {
+			clone = posix_acl_clone(acl, GFP_KERNEL);
+			error = -ENOMEM;
+			if (!clone)
+				goto cleanup;
+			ops->setacl(inode, ACL_TYPE_DEFAULT, clone);
+			posix_acl_release(clone);
+		}
+		clone = posix_acl_clone(acl, GFP_KERNEL);
+		error = -ENOMEM;
+		if (!clone)
+			goto cleanup;
+		error = posix_acl_create_masq(clone, &mode);
+		if (error >= 0) {
+			inode->i_mode = mode;
+			if (error > 0) {
+				ops->setacl(inode, ACL_TYPE_ACCESS, clone);
+			}
+		}
+		posix_acl_release(clone);
+	}
+	error = 0;
+
+cleanup:
+	posix_acl_release(acl);
+	return error;
+}
+
+int
+generic_acl_chmod(struct inode *inode, struct generic_acl_operations *ops)
+{
+	struct posix_acl *acl, *clone;
+	int error = 0;
+
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+	acl = ops->getacl(inode, ACL_TYPE_ACCESS);
+	if (acl) {
+		clone = posix_acl_clone(acl, GFP_KERNEL);
+		posix_acl_release(acl);
+		if (!clone)
+			return -ENOMEM;
+		error = posix_acl_chmod_masq(clone, inode->i_mode);
+		if (!error)
+			ops->setacl(inode, ACL_TYPE_ACCESS, clone);
+		posix_acl_release(clone);
+	}
+	return error;
+}

--
Andreas Gruenbacher <agruen@suse.de>
SUSE Labs, SUSE LINUX PRODUCTS GMBH


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC][PATCH 0/3] Access Control Lists for tmpfs and /dev/pts
  2005-02-02 16:13 [RFC][PATCH 0/3] Access Control Lists for tmpfs and /dev/pts Andreas Gruenbacher
                   ` (2 preceding siblings ...)
  2005-02-02 16:29 ` [RFC][PATCH 1/3] Generic infrastructure for acls Andreas Gruenbacher
@ 2005-02-02 16:55 ` Christoph Hellwig
  2005-02-02 17:37   ` Andreas Gruenbacher
  3 siblings, 1 reply; 7+ messages in thread
From: Christoph Hellwig @ 2005-02-02 16:55 UTC (permalink / raw)
  To: Andreas Gruenbacher; +Cc: linux-kernel, Chris Mason

On Wed, Feb 02, 2005 at 05:13:40PM +0100, Andreas Gruenbacher wrote:
> Here is a set of three patches which implement some general
> infrastructure and on top of that, acls for tmpfs and /dev/pts files.

Why would you want ACLs on /dev/pts?


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC][PATCH 0/3] Access Control Lists for tmpfs and /dev/pts
  2005-02-02 16:55 ` [RFC][PATCH 0/3] Access Control Lists for tmpfs and /dev/pts Christoph Hellwig
@ 2005-02-02 17:37   ` Andreas Gruenbacher
  2005-08-04 19:39     ` Catalin Patulea
  0 siblings, 1 reply; 7+ messages in thread
From: Andreas Gruenbacher @ 2005-02-02 17:37 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-kernel@vger.kernel.org, Chris Mason

On Wed, 2005-02-02 at 17:55, Christoph Hellwig wrote:
> On Wed, Feb 02, 2005 at 05:13:40PM +0100, Andreas Gruenbacher wrote:
> > Here is a set of three patches which implement some general
> > infrastructure and on top of that, acls for tmpfs and /dev/pts files.
> 
> Why would you want ACLs on /dev/pts?

That's actually a good question. The patch allows to give several people
access to the same terminal, which sometimes comes in handy with tools
like screen (at least in its current version), and that's what the patch
originally was meant for. I've just talked this over this with one of
the maintainers though, and there are probably better ways than handling
this at the file permission level, like passing open file descriptors
between processes. So unless somebody comes up with a convincing
application, that patch probably should stay out.

Cheers,
-- 
Andreas Gruenbacher <agruen@suse.de>
SUSE Labs, SUSE LINUX GMBH


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC][PATCH 0/3] Access Control Lists for tmpfs and /dev/pts
  2005-02-02 17:37   ` Andreas Gruenbacher
@ 2005-08-04 19:39     ` Catalin Patulea
  0 siblings, 0 replies; 7+ messages in thread
From: Catalin Patulea @ 2005-08-04 19:39 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: Christoph Hellwig, linux-kernel@vger.kernel.org, Chris Mason

On Wed, 2 Feb 2005, Andreas Gruenbacher wrote:

> On Wed, 2005-02-02 at 17:55, Christoph Hellwig wrote:
>> On Wed, Feb 02, 2005 at 05:13:40PM +0100, Andreas Gruenbacher wrote:
>>> Here is a set of three patches which implement some general
>>> infrastructure and on top of that, acls for tmpfs and /dev/pts files.
>>
>> Why would you want ACLs on /dev/pts?
>
> That's actually a good question. The patch allows to give several people
> access to the same terminal, which sometimes comes in handy with tools
> like screen (at least in its current version), and that's what the patch
> originally was meant for. I've just talked this over this with one of
> the maintainers though, and there are probably better ways than handling
> this at the file permission level, like passing open file descriptors
> between processes. So unless somebody comes up with a convincing
> application, that patch probably should stay out.
Aside from the above reason, I believe the mechanism behind the write 
command should also be considered. The notifications generated by write 
can currently be enabled and disabled only through an "all-on" or 
"all-off" mechanism - it doesn't leave room for user- or group-specific 
permissions because it's based on the mode of the TTY special file.

ACL support in devpts would allow much more fine-grained control of who 
is allowed and who is denied access to writing messages on your terminal.
This would come in very handy and I personally believe it should be 
possible to have such control.

Sorry for the random post and thanks for considering this reason,
Catalin Patulea
>
> Cheers,
> --
> Andreas Gruenbacher <agruen@suse.de>
> SUSE Labs, SUSE LINUX GMBH
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>
>

-----------------------------------------
Catalin Patulea       VV Volunteer 2002,3
http://vv.carleton.ca/~cat/  VV HI 2004,5
cat@vv.carleton.ca

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2005-08-04 19:44 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-02-02 16:13 [RFC][PATCH 0/3] Access Control Lists for tmpfs and /dev/pts Andreas Gruenbacher
2005-02-02 16:25 ` [RFC][PATCH 3/3] Access Control Lists for /dev/pts Andreas Gruenbacher
2005-02-02 16:25 ` [RFC][PATCH 2/3] Access Control Lists for tmpfs Andreas Gruenbacher
2005-02-02 16:29 ` [RFC][PATCH 1/3] Generic infrastructure for acls Andreas Gruenbacher
2005-02-02 16:55 ` [RFC][PATCH 0/3] Access Control Lists for tmpfs and /dev/pts Christoph Hellwig
2005-02-02 17:37   ` Andreas Gruenbacher
2005-08-04 19:39     ` Catalin Patulea

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox