summaryrefslogtreecommitdiff
path: root/fs/overlayfs/inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-14 17:23:33 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-14 17:23:33 -0700
commit1a892b485f328224b4882818f84fcc0a3208677d (patch)
treec0ec8fd39c2cdcb00996ac42e7f253f8157cf41d /fs/overlayfs/inode.c
parent5d89d9f502f9c33ed0270d716f238429861e1942 (diff)
parent7764235becf3b72bd124400fbffe670531322135 (diff)
downloadlwn-1a892b485f328224b4882818f84fcc0a3208677d.tar.gz
lwn-1a892b485f328224b4882818f84fcc0a3208677d.zip
Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull overlayfs updates from Miklos Szeredi: "This update contains fixes to the "use mounter's permission to access underlying layers" area, and miscellaneous other fixes and cleanups. No new features this time" * 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: ovl: use vfs_get_link() vfs: add vfs_get_link() helper ovl: use generic_readlink ovl: explain error values when removing acl from workdir ovl: Fix info leak in ovl_lookup_temp() ovl: during copy up, switch to mounter's creds early ovl: lookup: do getxattr with mounter's permission ovl: copy_up_xattr(): use strnlen
Diffstat (limited to 'fs/overlayfs/inode.c')
-rw-r--r--fs/overlayfs/inode.c44
1 files changed, 10 insertions, 34 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index c18d6a4ff456..c58f01babf30 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -19,6 +19,7 @@ static int ovl_copy_up_truncate(struct dentry *dentry)
struct dentry *parent;
struct kstat stat;
struct path lowerpath;
+ const struct cred *old_cred;
parent = dget_parent(dentry);
err = ovl_copy_up(parent);
@@ -26,12 +27,14 @@ static int ovl_copy_up_truncate(struct dentry *dentry)
goto out_dput_parent;
ovl_path_lower(dentry, &lowerpath);
- err = vfs_getattr(&lowerpath, &stat);
- if (err)
- goto out_dput_parent;
- stat.size = 0;
- err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat);
+ old_cred = ovl_override_creds(dentry->d_sb);
+ err = vfs_getattr(&lowerpath, &stat);
+ if (!err) {
+ stat.size = 0;
+ err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat);
+ }
+ revert_creds(old_cred);
out_dput_parent:
dput(parent);
@@ -153,45 +156,18 @@ static const char *ovl_get_link(struct dentry *dentry,
struct inode *inode,
struct delayed_call *done)
{
- struct dentry *realdentry;
- struct inode *realinode;
const struct cred *old_cred;
const char *p;
if (!dentry)
return ERR_PTR(-ECHILD);
- realdentry = ovl_dentry_real(dentry);
- realinode = realdentry->d_inode;
-
- if (WARN_ON(!realinode->i_op->get_link))
- return ERR_PTR(-EPERM);
-
old_cred = ovl_override_creds(dentry->d_sb);
- p = realinode->i_op->get_link(realdentry, realinode, done);
+ p = vfs_get_link(ovl_dentry_real(dentry), done);
revert_creds(old_cred);
return p;
}
-static int ovl_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
-{
- struct path realpath;
- struct inode *realinode;
- const struct cred *old_cred;
- int err;
-
- ovl_path_real(dentry, &realpath);
- realinode = realpath.dentry->d_inode;
-
- if (!realinode->i_op->readlink)
- return -EINVAL;
-
- old_cred = ovl_override_creds(dentry->d_sb);
- err = realinode->i_op->readlink(realpath.dentry, buf, bufsiz);
- revert_creds(old_cred);
- return err;
-}
-
bool ovl_is_private_xattr(const char *name)
{
return strncmp(name, OVL_XATTR_PREFIX,
@@ -375,7 +351,7 @@ static const struct inode_operations ovl_file_inode_operations = {
static const struct inode_operations ovl_symlink_inode_operations = {
.setattr = ovl_setattr,
.get_link = ovl_get_link,
- .readlink = ovl_readlink,
+ .readlink = generic_readlink,
.getattr = ovl_getattr,
.listxattr = ovl_listxattr,
.update_time = ovl_update_time,