linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [patch] fs: Allow user.* xattr in tmpfs
@ 2020-02-17 21:50 Pete Zaitcev
  2020-02-23 20:09 ` Hugh Dickins
  0 siblings, 1 reply; 2+ messages in thread
From: Pete Zaitcev @ 2020-02-17 21:50 UTC (permalink / raw)
  To: linux-mm; +Cc: Pete Zaitcev, Helge Deller, Hugh Dickins

Not having xattr in /tmp can be worked around usually by configuring
the affected software with TMPDIR=/var/tmp and the like, but I prefer
having this automated, if possible.

Signed-off-by: Pete Zaitcev <zaitcev@yahoo.com>
---
 fs/xattr.c            |    3 +++
 include/linux/xattr.h |   13 +++++++++++++
 mm/shmem.c            |   25 +++++++++++++++++++++++++
 3 files changed, 41 insertions(+)

diff --git a/fs/xattr.c b/fs/xattr.c
index 90dd78f0eb27..502567a4a478 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -896,6 +896,7 @@ int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
 			} else if (new_xattr) {
 				list_replace(&xattr->list, &new_xattr->list);
 			} else {
+				--xattrs->count;
 				list_del(&xattr->list);
 			}
 			goto out;
@@ -906,6 +907,7 @@ int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
 		err = -ENODATA;
 	} else {
 		list_add(&new_xattr->list, &xattrs->head);
+		xattrs->count++;
 		xattr = NULL;
 	}
 out:
@@ -988,5 +990,6 @@ void simple_xattr_list_add(struct simple_xattrs *xattrs,
 {
 	spin_lock(&xattrs->lock);
 	list_add(&new_xattr->list, &xattrs->head);
+	xattrs->count++;
 	spin_unlock(&xattrs->lock);
 }
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index 6dad031be3c2..e1ed5910ef5c 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -67,6 +67,7 @@ static inline const char *xattr_prefix(const struct xattr_handler *handler)
 struct simple_xattrs {
 	struct list_head head;
 	spinlock_t lock;
+	int count;
 };
 
 struct simple_xattr {
@@ -83,6 +84,7 @@ static inline void simple_xattrs_init(struct simple_xattrs *xattrs)
 {
 	INIT_LIST_HEAD(&xattrs->head);
 	spin_lock_init(&xattrs->lock);
+	xattrs->count = 0;
 }
 
 /*
@@ -96,6 +98,17 @@ static inline void simple_xattrs_free(struct simple_xattrs *xattrs)
 		kfree(xattr->name);
 		kfree(xattr);
 	}
+	xattrs->count = 0;
+}
+
+static inline int simple_xattrs_count(struct simple_xattrs *xattrs)
+{
+	int ret;
+
+	spin_lock(&xattrs->lock);
+	ret = xattrs->count;
+	spin_unlock(&xattrs->lock);
+	return ret;
 }
 
 struct simple_xattr *simple_xattr_alloc(const void *value, size_t size);
diff --git a/mm/shmem.c b/mm/shmem.c
index c8f7540ef048..0ce17afad30e 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -3246,6 +3246,30 @@ static int shmem_xattr_handler_set(const struct xattr_handler *handler,
 	return simple_xattr_set(&info->xattrs, name, value, size, flags);
 }
 
+static int shmem_xattr_handler_set_user(const struct xattr_handler *handler,
+				   struct dentry *unused, struct inode *inode,
+				   const char *name, const void *value,
+				   size_t size, int flags)
+{
+	struct shmem_inode_info *info = SHMEM_I(inode);
+	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
+
+	if (value) {
+		if (size > 8192)
+			return -EINVAL;
+		if (simple_xattrs_count(&info->xattrs) >= sbinfo->max_inodes)
+			return -ENOSPC;
+	}
+	name = xattr_full_name(handler, name);
+	return simple_xattr_set(&info->xattrs, name, value, size, flags);
+}
+
+static const struct xattr_handler shmem_user_xattr_handler = {
+	.prefix = XATTR_USER_PREFIX,
+	.get = shmem_xattr_handler_get,
+	.set = shmem_xattr_handler_set_user,
+};
+
 static const struct xattr_handler shmem_security_xattr_handler = {
 	.prefix = XATTR_SECURITY_PREFIX,
 	.get = shmem_xattr_handler_get,
@@ -3263,6 +3287,7 @@ static const struct xattr_handler *shmem_xattr_handlers[] = {
 	&posix_acl_access_xattr_handler,
 	&posix_acl_default_xattr_handler,
 #endif
+	&shmem_user_xattr_handler,
 	&shmem_security_xattr_handler,
 	&shmem_trusted_xattr_handler,
 	NULL


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

* Re: [patch] fs: Allow user.* xattr in tmpfs
  2020-02-17 21:50 [patch] fs: Allow user.* xattr in tmpfs Pete Zaitcev
@ 2020-02-23 20:09 ` Hugh Dickins
  0 siblings, 0 replies; 2+ messages in thread
From: Hugh Dickins @ 2020-02-23 20:09 UTC (permalink / raw)
  To: Pete Zaitcev; +Cc: linux-mm, Helge Deller, Hugh Dickins

On Mon, 17 Feb 2020, Pete Zaitcev wrote:

> Not having xattr in /tmp can be worked around usually by configuring
> the affected software with TMPDIR=/var/tmp and the like, but I prefer
> having this automated, if possible.
> 
> Signed-off-by: Pete Zaitcev <zaitcev@yahoo.com>

Thanks for looking into this - and thanks to Helge for reminding
that we discussed it before in private mail, 13 September 2018 most
recently (when I falsely implied that I might get around to doing it:
sorry, I have not).

Below looks like a bit of a misunderstanding of what I intended there.
Yes, I still think that accounting xattr memory consumption from the
space already (usually) limited by max_inodes is the best way forward
to enabling user xattrs on tmpfs, while limiting the damage they can do.

But, perhaps I'm misreading, here it looks as if you're allowing
max_inodes xattrs of size 8k on each inode?

No, I meant that we expect a memory size of, very approximately, 1k for
each inode+dentry, so max_inodes*1k is a limited pool of memory, from
which we currently count just the inodes, but could reasonably count
xattr memory too - but will need to extend to byte-counting for that. 

Hugh

> ---
>  fs/xattr.c            |    3 +++
>  include/linux/xattr.h |   13 +++++++++++++
>  mm/shmem.c            |   25 +++++++++++++++++++++++++
>  3 files changed, 41 insertions(+)
> 
> diff --git a/fs/xattr.c b/fs/xattr.c
> index 90dd78f0eb27..502567a4a478 100644
> --- a/fs/xattr.c
> +++ b/fs/xattr.c
> @@ -896,6 +896,7 @@ int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
>  			} else if (new_xattr) {
>  				list_replace(&xattr->list, &new_xattr->list);
>  			} else {
> +				--xattrs->count;
>  				list_del(&xattr->list);
>  			}
>  			goto out;
> @@ -906,6 +907,7 @@ int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
>  		err = -ENODATA;
>  	} else {
>  		list_add(&new_xattr->list, &xattrs->head);
> +		xattrs->count++;
>  		xattr = NULL;
>  	}
>  out:
> @@ -988,5 +990,6 @@ void simple_xattr_list_add(struct simple_xattrs *xattrs,
>  {
>  	spin_lock(&xattrs->lock);
>  	list_add(&new_xattr->list, &xattrs->head);
> +	xattrs->count++;
>  	spin_unlock(&xattrs->lock);
>  }
> diff --git a/include/linux/xattr.h b/include/linux/xattr.h
> index 6dad031be3c2..e1ed5910ef5c 100644
> --- a/include/linux/xattr.h
> +++ b/include/linux/xattr.h
> @@ -67,6 +67,7 @@ static inline const char *xattr_prefix(const struct xattr_handler *handler)
>  struct simple_xattrs {
>  	struct list_head head;
>  	spinlock_t lock;
> +	int count;
>  };
>  
>  struct simple_xattr {
> @@ -83,6 +84,7 @@ static inline void simple_xattrs_init(struct simple_xattrs *xattrs)
>  {
>  	INIT_LIST_HEAD(&xattrs->head);
>  	spin_lock_init(&xattrs->lock);
> +	xattrs->count = 0;
>  }
>  
>  /*
> @@ -96,6 +98,17 @@ static inline void simple_xattrs_free(struct simple_xattrs *xattrs)
>  		kfree(xattr->name);
>  		kfree(xattr);
>  	}
> +	xattrs->count = 0;
> +}
> +
> +static inline int simple_xattrs_count(struct simple_xattrs *xattrs)
> +{
> +	int ret;
> +
> +	spin_lock(&xattrs->lock);
> +	ret = xattrs->count;
> +	spin_unlock(&xattrs->lock);
> +	return ret;
>  }
>  
>  struct simple_xattr *simple_xattr_alloc(const void *value, size_t size);
> diff --git a/mm/shmem.c b/mm/shmem.c
> index c8f7540ef048..0ce17afad30e 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -3246,6 +3246,30 @@ static int shmem_xattr_handler_set(const struct xattr_handler *handler,
>  	return simple_xattr_set(&info->xattrs, name, value, size, flags);
>  }
>  
> +static int shmem_xattr_handler_set_user(const struct xattr_handler *handler,
> +				   struct dentry *unused, struct inode *inode,
> +				   const char *name, const void *value,
> +				   size_t size, int flags)
> +{
> +	struct shmem_inode_info *info = SHMEM_I(inode);
> +	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
> +
> +	if (value) {
> +		if (size > 8192)
> +			return -EINVAL;
> +		if (simple_xattrs_count(&info->xattrs) >= sbinfo->max_inodes)
> +			return -ENOSPC;
> +	}
> +	name = xattr_full_name(handler, name);
> +	return simple_xattr_set(&info->xattrs, name, value, size, flags);
> +}
> +
> +static const struct xattr_handler shmem_user_xattr_handler = {
> +	.prefix = XATTR_USER_PREFIX,
> +	.get = shmem_xattr_handler_get,
> +	.set = shmem_xattr_handler_set_user,
> +};
> +
>  static const struct xattr_handler shmem_security_xattr_handler = {
>  	.prefix = XATTR_SECURITY_PREFIX,
>  	.get = shmem_xattr_handler_get,
> @@ -3263,6 +3287,7 @@ static const struct xattr_handler *shmem_xattr_handlers[] = {
>  	&posix_acl_access_xattr_handler,
>  	&posix_acl_default_xattr_handler,
>  #endif
> +	&shmem_user_xattr_handler,
>  	&shmem_security_xattr_handler,
>  	&shmem_trusted_xattr_handler,
>  	NULL
> 


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

end of thread, other threads:[~2020-02-23 20:10 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-17 21:50 [patch] fs: Allow user.* xattr in tmpfs Pete Zaitcev
2020-02-23 20:09 ` Hugh Dickins

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).