public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Andreas Gruenbacher <agruen@suse.de>
To: James Morris <jmorris@redhat.com>
Cc: Andrew Morton <akpm@osdl.org>,
	<viro@parcelfarce.linux.theplanet.co.uk>,
	Stephen Smalley <sds@epoch.ncsc.mil>,
	Christoph Hellwig <hch@infradead.org>,
	<linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 1/6] xattr consolidation v2 - generic xattr API
Date: Sun, 19 Sep 2004 01:31:01 +0200	[thread overview]
Message-ID: <200409190131.01625.agruen@suse.de> (raw)
In-Reply-To: <Xine.LNX.4.44.0409180305300.10905-100000@thoron.boston.redhat.com>

Hello,

the patches look good except for a theoretical race in generic_listxattr:

> +ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t
> buffer_size) +{
> +	struct inode *inode = dentry->d_inode;
> +	struct xattr_handler *handler, **handlers = inode->i_sb->s_xattr;
> +	unsigned int size = 0;
> +	char *buf;
> +
> +	for_each_xattr_handler(handlers, handler)
> +		size += handler->list(inode, NULL, NULL, 0);

We might setxattr here and the name list might change between the two passes.

> [...]
> +	for_each_xattr_handler(handlers, handler)
> +		buf += handler->list(inode, buf, NULL, 0);
> +
> +	return size;
> +}

This currently is only relevant for the security attribute. Selinux always 
returns the same attribute name so it can't trigger this problem, but other 
LSMs might do something different.

We can add a list_size parameter to xattr_handler->list to get this fixed. We 
should change the name_len parameter of xattr_handler->list from int to 
size_t:

Index: linux-2.6.9-rc1/include/linux/xattr.h
===================================================================
--- linux-2.6.9-rc1.orig/include/linux/xattr.h
+++ linux-2.6.9-rc1/include/linux/xattr.h
@@ -17,8 +17,8 @@
 
 struct xattr_handler {
 	char *prefix;
-	size_t (*list)(struct inode *inode, char *list, const char *name,
-		       int name_len);
+	size_t (*list)(struct inode *inode, char *list, size_t list_size,
+		       const char *name, size_t name_len);
 	int (*get)(struct inode *inode, const char *name, void *buffer,
 		   size_t size);
 	int (*set)(struct inode *inode, const char *name, const void *buffer,
Index: linux-2.6.9-rc1/fs/xattr.c
===================================================================
--- linux-2.6.9-rc1.orig/fs/xattr.c
+++ linux-2.6.9-rc1/fs/xattr.c
@@ -397,23 +397,22 @@ ssize_t generic_listxattr(struct dentry 
 	struct inode *inode = dentry->d_inode;
 	struct xattr_handler *handler, **handlers = inode->i_sb->s_xattr;
 	unsigned int size = 0;
-	char *buf;
-
-	for_each_xattr_handler(handlers, handler)
-		size += handler->list(inode, NULL, NULL, 0);
-
-	if (!buffer)
-		return size;
-		
-	if (size > buffer_size)
-		return -ERANGE;
-
-	buf = buffer;
-	handlers = inode->i_sb->s_xattr;
-	
-	for_each_xattr_handler(handlers, handler)
-		buf += handler->list(inode, buf, NULL, 0);
 
+	if (!buffer) {
+		for_each_xattr_handler(handlers, handler)
+			size += handler->list(inode, NULL, 0, NULL, 0);
+	} else {
+		char *buf = buffer;
+
+		for_each_xattr_handler(handlers, handler) {
+			size = handler->list(inode, buf, buffer_size, NULL, 0);
+			if (size > buffer_size)
+				return -ERANGE;
+			buf += size;
+			buffer_size -= size;
+		}
+		size = buf - buffer;
+	}
 	return size;
 }

The current users can easily be converted. As a side effect, the 
ext2_xattr_list() and ext3_xattr_list() functions could also be changed to do 
a single iteration only.

I also noticed that your additions to fs/xattr.c use a slightly different 
coding style than the rest of the file. You might want to change that as 
well.

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

  reply	other threads:[~2004-09-18 23:37 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <Xine.LNX.4.44.0409180252090.10905@thoron.boston.redhat.com>
2004-09-18  7:20 ` [PATCH 1/6] xattr consolidation v2 - generic xattr API James Morris
2004-09-18 23:31   ` Andreas Gruenbacher [this message]
2004-09-18 23:47     ` James Morris
2004-09-19 10:13       ` Andreas Gruenbacher
2004-09-19 14:46         ` James Morris
2004-09-20 17:50   ` Will Dyson
2004-09-20 23:07     ` James Morris
2004-09-21  3:25       ` Will Dyson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200409190131.01625.agruen@suse.de \
    --to=agruen@suse.de \
    --cc=akpm@osdl.org \
    --cc=hch@infradead.org \
    --cc=jmorris@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sds@epoch.ncsc.mil \
    --cc=viro@parcelfarce.linux.theplanet.co.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox