Commit 0e585ccc authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Miklos Szeredi

ovl: Switch to generic_removexattr

Commit d837a49b ("ovl: fix POSIX ACL setting") switches from
iop->setxattr from ovl_setxattr to generic_setxattr, so switch from
ovl_removexattr to generic_removexattr as well.  As far as permission
checking goes, the same rules should apply in either case.

While doing that, rename ovl_setxattr to ovl_xattr_set to indicate that
this is not an iop->setxattr implementation and remove the unused inode
argument.

Move ovl_other_xattr_set above ovl_own_xattr_set so that they match the
order of handlers in ovl_xattr_handlers.
Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
Fixes: d837a49b ("ovl: fix POSIX ACL setting")
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent 0c97be22
...@@ -1006,7 +1006,7 @@ const struct inode_operations ovl_dir_inode_operations = { ...@@ -1006,7 +1006,7 @@ const struct inode_operations ovl_dir_inode_operations = {
.setxattr = generic_setxattr, .setxattr = generic_setxattr,
.getxattr = ovl_getxattr, .getxattr = ovl_getxattr,
.listxattr = ovl_listxattr, .listxattr = ovl_listxattr,
.removexattr = ovl_removexattr, .removexattr = generic_removexattr,
.get_acl = ovl_get_acl, .get_acl = ovl_get_acl,
.update_time = ovl_update_time, .update_time = ovl_update_time,
}; };
...@@ -198,25 +198,38 @@ bool ovl_is_private_xattr(const char *name) ...@@ -198,25 +198,38 @@ bool ovl_is_private_xattr(const char *name)
sizeof(OVL_XATTR_PREFIX) - 1) == 0; sizeof(OVL_XATTR_PREFIX) - 1) == 0;
} }
int ovl_setxattr(struct dentry *dentry, struct inode *inode, int ovl_xattr_set(struct dentry *dentry, const char *name, const void *value,
const char *name, const void *value,
size_t size, int flags) size_t size, int flags)
{ {
int err; int err;
struct dentry *upperdentry; struct path realpath;
enum ovl_path_type type = ovl_path_real(dentry, &realpath);
const struct cred *old_cred; const struct cred *old_cred;
err = ovl_want_write(dentry); err = ovl_want_write(dentry);
if (err) if (err)
goto out; goto out;
if (!value && !OVL_TYPE_UPPER(type)) {
err = vfs_getxattr(realpath.dentry, name, NULL, 0);
if (err < 0)
goto out_drop_write;
}
err = ovl_copy_up(dentry); err = ovl_copy_up(dentry);
if (err) if (err)
goto out_drop_write; goto out_drop_write;
upperdentry = ovl_dentry_upper(dentry); if (!OVL_TYPE_UPPER(type))
ovl_path_upper(dentry, &realpath);
old_cred = ovl_override_creds(dentry->d_sb); old_cred = ovl_override_creds(dentry->d_sb);
err = vfs_setxattr(upperdentry, name, value, size, flags); if (value)
err = vfs_setxattr(realpath.dentry, name, value, size, flags);
else {
WARN_ON(flags != XATTR_REPLACE);
err = vfs_removexattr(realpath.dentry, name);
}
revert_creds(old_cred); revert_creds(old_cred);
out_drop_write: out_drop_write:
...@@ -272,42 +285,6 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) ...@@ -272,42 +285,6 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
return res; return res;
} }
int ovl_removexattr(struct dentry *dentry, const char *name)
{
int err;
struct path realpath;
enum ovl_path_type type = ovl_path_real(dentry, &realpath);
const struct cred *old_cred;
err = ovl_want_write(dentry);
if (err)
goto out;
err = -ENODATA;
if (ovl_is_private_xattr(name))
goto out_drop_write;
if (!OVL_TYPE_UPPER(type)) {
err = vfs_getxattr(realpath.dentry, name, NULL, 0);
if (err < 0)
goto out_drop_write;
err = ovl_copy_up(dentry);
if (err)
goto out_drop_write;
ovl_path_upper(dentry, &realpath);
}
old_cred = ovl_override_creds(dentry->d_sb);
err = vfs_removexattr(realpath.dentry, name);
revert_creds(old_cred);
out_drop_write:
ovl_drop_write(dentry);
out:
return err;
}
struct posix_acl *ovl_get_acl(struct inode *inode, int type) struct posix_acl *ovl_get_acl(struct inode *inode, int type)
{ {
struct inode *realinode = ovl_inode_real(inode, NULL); struct inode *realinode = ovl_inode_real(inode, NULL);
...@@ -393,7 +370,7 @@ static const struct inode_operations ovl_file_inode_operations = { ...@@ -393,7 +370,7 @@ static const struct inode_operations ovl_file_inode_operations = {
.setxattr = generic_setxattr, .setxattr = generic_setxattr,
.getxattr = ovl_getxattr, .getxattr = ovl_getxattr,
.listxattr = ovl_listxattr, .listxattr = ovl_listxattr,
.removexattr = ovl_removexattr, .removexattr = generic_removexattr,
.get_acl = ovl_get_acl, .get_acl = ovl_get_acl,
.update_time = ovl_update_time, .update_time = ovl_update_time,
}; };
...@@ -406,7 +383,7 @@ static const struct inode_operations ovl_symlink_inode_operations = { ...@@ -406,7 +383,7 @@ static const struct inode_operations ovl_symlink_inode_operations = {
.setxattr = generic_setxattr, .setxattr = generic_setxattr,
.getxattr = ovl_getxattr, .getxattr = ovl_getxattr,
.listxattr = ovl_listxattr, .listxattr = ovl_listxattr,
.removexattr = ovl_removexattr, .removexattr = generic_removexattr,
.update_time = ovl_update_time, .update_time = ovl_update_time,
}; };
......
...@@ -185,13 +185,11 @@ void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt, ...@@ -185,13 +185,11 @@ void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt,
/* inode.c */ /* inode.c */
int ovl_setattr(struct dentry *dentry, struct iattr *attr); int ovl_setattr(struct dentry *dentry, struct iattr *attr);
int ovl_permission(struct inode *inode, int mask); int ovl_permission(struct inode *inode, int mask);
int ovl_setxattr(struct dentry *dentry, struct inode *inode, int ovl_xattr_set(struct dentry *dentry, const char *name, const void *value,
const char *name, const void *value,
size_t size, int flags); size_t size, int flags);
ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode, ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode,
const char *name, void *value, size_t size); const char *name, void *value, size_t size);
ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
int ovl_removexattr(struct dentry *dentry, const char *name);
struct posix_acl *ovl_get_acl(struct inode *inode, int type); struct posix_acl *ovl_get_acl(struct inode *inode, int type);
int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags); int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags);
int ovl_update_time(struct inode *inode, struct timespec *ts, int flags); int ovl_update_time(struct inode *inode, struct timespec *ts, int flags);
......
...@@ -1018,27 +1018,27 @@ ovl_posix_acl_xattr_set(const struct xattr_handler *handler, ...@@ -1018,27 +1018,27 @@ ovl_posix_acl_xattr_set(const struct xattr_handler *handler,
posix_acl_release(acl); posix_acl_release(acl);
return ovl_setxattr(dentry, inode, handler->name, value, size, flags); return ovl_xattr_set(dentry, handler->name, value, size, flags);
out_acl_release: out_acl_release:
posix_acl_release(acl); posix_acl_release(acl);
return err; return err;
} }
static int ovl_other_xattr_set(const struct xattr_handler *handler, static int ovl_own_xattr_set(const struct xattr_handler *handler,
struct dentry *dentry, struct inode *inode, struct dentry *dentry, struct inode *inode,
const char *name, const void *value, const char *name, const void *value,
size_t size, int flags) size_t size, int flags)
{ {
return ovl_setxattr(dentry, inode, name, value, size, flags); return -EPERM;
} }
static int ovl_own_xattr_set(const struct xattr_handler *handler, static int ovl_other_xattr_set(const struct xattr_handler *handler,
struct dentry *dentry, struct inode *inode, struct dentry *dentry, struct inode *inode,
const char *name, const void *value, const char *name, const void *value,
size_t size, int flags) size_t size, int flags)
{ {
return -EPERM; return ovl_xattr_set(dentry, name, value, size, flags);
} }
static const struct xattr_handler __maybe_unused static const struct xattr_handler __maybe_unused
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment