ovl: lookup: do getxattr with mounter's permission
The getxattr() in ovl_is_opaquedir() was missed when converting all operations on underlying fs to be done under mounter's permission. This patch fixes this by moving the ovl_override_creds()/revert_creds() out from ovl_lookup_real() to ovl_lookup(). Also convert to using vfs_getxattr() instead of directly calling i_op->getxattr(). Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
8b326c61de
commit
2b6bc7f48d
|
@ -273,12 +273,11 @@ static bool ovl_is_opaquedir(struct dentry *dentry)
|
|||
{
|
||||
int res;
|
||||
char val;
|
||||
struct inode *inode = dentry->d_inode;
|
||||
|
||||
if (!S_ISDIR(inode->i_mode) || !inode->i_op->getxattr)
|
||||
if (!d_is_dir(dentry))
|
||||
return false;
|
||||
|
||||
res = inode->i_op->getxattr(dentry, inode, OVL_XATTR_OPAQUE, &val, 1);
|
||||
res = vfs_getxattr(dentry, OVL_XATTR_OPAQUE, &val, 1);
|
||||
if (res == 1 && val == 'y')
|
||||
return true;
|
||||
|
||||
|
@ -419,16 +418,12 @@ static bool ovl_dentry_weird(struct dentry *dentry)
|
|||
DCACHE_OP_COMPARE);
|
||||
}
|
||||
|
||||
static inline struct dentry *ovl_lookup_real(struct super_block *ovl_sb,
|
||||
struct dentry *dir,
|
||||
static inline struct dentry *ovl_lookup_real(struct dentry *dir,
|
||||
const struct qstr *name)
|
||||
{
|
||||
const struct cred *old_cred;
|
||||
struct dentry *dentry;
|
||||
|
||||
old_cred = ovl_override_creds(ovl_sb);
|
||||
dentry = lookup_one_len_unlocked(name->name, dir, name->len);
|
||||
revert_creds(old_cred);
|
||||
|
||||
if (IS_ERR(dentry)) {
|
||||
if (PTR_ERR(dentry) == -ENOENT)
|
||||
|
@ -469,6 +464,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
|
|||
unsigned int flags)
|
||||
{
|
||||
struct ovl_entry *oe;
|
||||
const struct cred *old_cred;
|
||||
struct ovl_entry *poe = dentry->d_parent->d_fsdata;
|
||||
struct path *stack = NULL;
|
||||
struct dentry *upperdir, *upperdentry = NULL;
|
||||
|
@ -479,9 +475,10 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
|
|||
unsigned int i;
|
||||
int err;
|
||||
|
||||
old_cred = ovl_override_creds(dentry->d_sb);
|
||||
upperdir = ovl_upperdentry_dereference(poe);
|
||||
if (upperdir) {
|
||||
this = ovl_lookup_real(dentry->d_sb, upperdir, &dentry->d_name);
|
||||
this = ovl_lookup_real(upperdir, &dentry->d_name);
|
||||
err = PTR_ERR(this);
|
||||
if (IS_ERR(this))
|
||||
goto out;
|
||||
|
@ -514,8 +511,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
|
|||
bool opaque = false;
|
||||
struct path lowerpath = poe->lowerstack[i];
|
||||
|
||||
this = ovl_lookup_real(dentry->d_sb,
|
||||
lowerpath.dentry, &dentry->d_name);
|
||||
this = ovl_lookup_real(lowerpath.dentry, &dentry->d_name);
|
||||
err = PTR_ERR(this);
|
||||
if (IS_ERR(this)) {
|
||||
/*
|
||||
|
@ -588,6 +584,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
|
|||
ovl_copyattr(realdentry->d_inode, inode);
|
||||
}
|
||||
|
||||
revert_creds(old_cred);
|
||||
oe->opaque = upperopaque;
|
||||
oe->__upperdentry = upperdentry;
|
||||
memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr);
|
||||
|
@ -606,6 +603,7 @@ out_put:
|
|||
out_put_upper:
|
||||
dput(upperdentry);
|
||||
out:
|
||||
revert_creds(old_cred);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue