Commit 2b6bc7f4 authored by Miklos Szeredi's avatar Miklos Szeredi

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: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent 8b326c61
...@@ -273,12 +273,11 @@ static bool ovl_is_opaquedir(struct dentry *dentry) ...@@ -273,12 +273,11 @@ static bool ovl_is_opaquedir(struct dentry *dentry)
{ {
int res; int res;
char val; 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; 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') if (res == 1 && val == 'y')
return true; return true;
...@@ -419,16 +418,12 @@ static bool ovl_dentry_weird(struct dentry *dentry) ...@@ -419,16 +418,12 @@ static bool ovl_dentry_weird(struct dentry *dentry)
DCACHE_OP_COMPARE); DCACHE_OP_COMPARE);
} }
static inline struct dentry *ovl_lookup_real(struct super_block *ovl_sb, static inline struct dentry *ovl_lookup_real(struct dentry *dir,
struct dentry *dir,
const struct qstr *name) const struct qstr *name)
{ {
const struct cred *old_cred;
struct dentry *dentry; struct dentry *dentry;
old_cred = ovl_override_creds(ovl_sb);
dentry = lookup_one_len_unlocked(name->name, dir, name->len); dentry = lookup_one_len_unlocked(name->name, dir, name->len);
revert_creds(old_cred);
if (IS_ERR(dentry)) { if (IS_ERR(dentry)) {
if (PTR_ERR(dentry) == -ENOENT) if (PTR_ERR(dentry) == -ENOENT)
...@@ -469,6 +464,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ...@@ -469,6 +464,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
unsigned int flags) unsigned int flags)
{ {
struct ovl_entry *oe; struct ovl_entry *oe;
const struct cred *old_cred;
struct ovl_entry *poe = dentry->d_parent->d_fsdata; struct ovl_entry *poe = dentry->d_parent->d_fsdata;
struct path *stack = NULL; struct path *stack = NULL;
struct dentry *upperdir, *upperdentry = NULL; struct dentry *upperdir, *upperdentry = NULL;
...@@ -479,9 +475,10 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ...@@ -479,9 +475,10 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
unsigned int i; unsigned int i;
int err; int err;
old_cred = ovl_override_creds(dentry->d_sb);
upperdir = ovl_upperdentry_dereference(poe); upperdir = ovl_upperdentry_dereference(poe);
if (upperdir) { 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); err = PTR_ERR(this);
if (IS_ERR(this)) if (IS_ERR(this))
goto out; goto out;
...@@ -514,8 +511,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ...@@ -514,8 +511,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
bool opaque = false; bool opaque = false;
struct path lowerpath = poe->lowerstack[i]; struct path lowerpath = poe->lowerstack[i];
this = ovl_lookup_real(dentry->d_sb, this = ovl_lookup_real(lowerpath.dentry, &dentry->d_name);
lowerpath.dentry, &dentry->d_name);
err = PTR_ERR(this); err = PTR_ERR(this);
if (IS_ERR(this)) { if (IS_ERR(this)) {
/* /*
...@@ -588,6 +584,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ...@@ -588,6 +584,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
ovl_copyattr(realdentry->d_inode, inode); ovl_copyattr(realdentry->d_inode, inode);
} }
revert_creds(old_cred);
oe->opaque = upperopaque; oe->opaque = upperopaque;
oe->__upperdentry = upperdentry; oe->__upperdentry = upperdentry;
memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr); memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr);
...@@ -606,6 +603,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ...@@ -606,6 +603,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
out_put_upper: out_put_upper:
dput(upperdentry); dput(upperdentry);
out: out:
revert_creds(old_cred);
return ERR_PTR(err); return ERR_PTR(err);
} }
......
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