From: Herbert Pƶtzl <herbert@13thfloor.at>
Previously, the xattr VFS interface did not regard the VFS context
from which a dentry was acquired.
As the per-vfsmount flags may now affect the permissions, the vfsmount
structure must now be passed into the *xattr interface.
Checks are also added to setxattr() and removexattr() for the
MNT_RDONLY flag via MNT_IS_RDONLY, and EROFS returned accordingly.
Acked-by: Sam Vilain <sam.vilain@catalyst.net.nz>
--- fs/xattr.c | 23 +++++++++++++++-------- 1 files changed, 15 insertions(+), 8 deletions(-) diff --git a/fs/xattr.c b/fs/xattr.c index 80eca7d..ad83a51 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -17,6 +17,7 @@ #include <linux/syscalls.h> #include <linux/module.h> #include <linux/fsnotify.h> +#include <linux/mount.h> #include <asm/uaccess.h> @@ -167,7 +168,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr); */ static long setxattr(struct dentry *d, char __user *name, void __user *value, - size_t size, int flags) + size_t size, int flags, struct vfsmount *mnt) { int error; void *kvalue = NULL; @@ -194,6 +195,9 @@ setxattr(struct dentry *d, char __user * } } + if (MNT_IS_RDONLY(mnt)) + return -EROFS; + error = vfs_setxattr(d, kname, kvalue, size, flags); kfree(kvalue); return error; @@ -209,7 +213,7 @@ sys_setxattr(char __user *path, char __u error = user_path_walk(path, &nd); if (error) return error; - error = setxattr(nd.dentry, name, value, size, flags); + error = setxattr(nd.dentry, name, value, size, flags, nd.mnt); path_release(&nd); return error; } @@ -224,7 +228,7 @@ sys_lsetxattr(char __user *path, char __ error = user_path_walk_link(path, &nd); if (error) return error; - error = setxattr(nd.dentry, name, value, size, flags); + error = setxattr(nd.dentry, name, value, size, flags, nd.mnt); path_release(&nd); return error; } @@ -239,7 +243,7 @@ sys_fsetxattr(int fd, char __user *name, f = fget(fd); if (!f) return error; - error = setxattr(f->f_dentry, name, value, size, flags); + error = setxattr(f->f_dentry, name, value, size, flags, f->f_vfsmnt); fput(f); return error; } @@ -412,7 +416,7 @@ sys_flistxattr(int fd, char __user *list * Extended attribute REMOVE operations */ static long -removexattr(struct dentry *d, char __user *name) +removexattr(struct dentry *d, char __user *name, struct vfsmount *mnt) { int error; char kname[XATTR_NAME_MAX + 1]; @@ -423,6 +427,9 @@ removexattr(struct dentry *d, char __use if (error < 0) return error; + if (MNT_IS_RDONLY(mnt)) + return -EROFS; + return vfs_removexattr(d, kname); } @@ -435,7 +442,7 @@ sys_removexattr(char __user *path, char error = user_path_walk(path, &nd); if (error) return error; - error = removexattr(nd.dentry, name); + error = removexattr(nd.dentry, name, nd.mnt); path_release(&nd); return error; } @@ -449,7 +456,7 @@ sys_lremovexattr(char __user *path, char error = user_path_walk_link(path, &nd); if (error) return error; - error = removexattr(nd.dentry, name); + error = removexattr(nd.dentry, name, nd.mnt); path_release(&nd); return error; } @@ -463,7 +470,7 @@ sys_fremovexattr(int fd, char __user *na f = fget(fd); if (!f) return error; - error = removexattr(f->f_dentry, name); + error = removexattr(f->f_dentry, name, f->f_vfsmnt); fput(f); return error; } _______________________________________________ Vserver mailing list Vserver@list.linux-vserver.org http://list.linux-vserver.org/mailman/listinfo/vserverReceived on Mon Feb 27 05:49:55 2006