summaryrefslogtreecommitdiffstats
path: root/fs/overlayfs/inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-11-23 05:55:42 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2024-11-23 05:55:42 +0100
commite7675238b9bf4db0b872d5dbcd53efa31914c98f (patch)
treea01d4a527d3f37b24522002b708451ab29fc078f /fs/overlayfs/inode.c
parentMerge tag 'unicode-next-6.13' of git://git.kernel.org/pub/scm/linux/kernel/gi... (diff)
parentovl: Filter invalid inodes with missing lookup function (diff)
downloadlinux-e7675238b9bf4db0b872d5dbcd53efa31914c98f.tar.xz
linux-e7675238b9bf4db0b872d5dbcd53efa31914c98f.zip
Merge tag 'ovl-update-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/overlayfs/vfs
Pull overlayfs updates from Amir Goldstein: - Fix a syzbot reported NULL pointer deref with bfs lower layers - Fix a copy up failure of large file from lower fuse fs - Followup cleanup of backing_file API from Miklos - Introduction and use of revert/override_creds_light() helpers, that were suggested by Christian as a mitigation to cache line bouncing and false sharing of fields in overlayfs creator_cred long lived struct cred copy. - Store up to two backing file references (upper and lower) in an ovl_file container instead of storing a single backing file in file->private_data. This is used to avoid the practice of opening a short lived backing file for the duration of some file operations and to avoid the specialized use of FDPUT_FPUT in such occasions, that was getting in the way of Al's fd_file() conversions. * tag 'ovl-update-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/overlayfs/vfs: ovl: Filter invalid inodes with missing lookup function ovl: convert ovl_real_fdget() callers to ovl_real_file() ovl: convert ovl_real_fdget_path() callers to ovl_real_file_path() ovl: store upper real file in ovl_file struct ovl: allocate a container struct ovl_file for ovl private context ovl: do not open non-data lower file for fsync ovl: Optimize override/revert creds ovl: pass an explicit reference of creators creds to callers ovl: use wrapper ovl_revert_creds() fs/backing-file: Convert to revert/override_creds_light() cred: Add a light version of override/revert_creds() backing-file: clean up the API ovl: properly handle large files in ovl_security_fileattr
Diffstat (limited to 'fs/overlayfs/inode.c')
-rw-r--r--fs/overlayfs/inode.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 8b31f44c12cd..6f0e15f86c21 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -80,7 +80,7 @@ int ovl_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
inode_lock(upperdentry->d_inode);
old_cred = ovl_override_creds(dentry->d_sb);
err = ovl_do_notify_change(ofs, upperdentry, attr);
- revert_creds(old_cred);
+ ovl_revert_creds(old_cred);
if (!err)
ovl_copyattr(dentry->d_inode);
inode_unlock(upperdentry->d_inode);
@@ -280,7 +280,7 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path,
stat->nlink = dentry->d_inode->i_nlink;
out:
- revert_creds(old_cred);
+ ovl_revert_creds(old_cred);
return err;
}
@@ -317,7 +317,7 @@ int ovl_permission(struct mnt_idmap *idmap,
mask |= MAY_READ;
}
err = inode_permission(mnt_idmap(realpath.mnt), realinode, mask);
- revert_creds(old_cred);
+ ovl_revert_creds(old_cred);
return err;
}
@@ -334,7 +334,7 @@ static const char *ovl_get_link(struct dentry *dentry,
old_cred = ovl_override_creds(dentry->d_sb);
p = vfs_get_link(ovl_dentry_real(dentry), done);
- revert_creds(old_cred);
+ ovl_revert_creds(old_cred);
return p;
}
@@ -469,7 +469,7 @@ struct posix_acl *do_ovl_get_acl(struct mnt_idmap *idmap,
old_cred = ovl_override_creds(inode->i_sb);
acl = ovl_get_acl_path(&realpath, posix_acl_xattr_name(type), noperm);
- revert_creds(old_cred);
+ ovl_revert_creds(old_cred);
}
return acl;
@@ -498,7 +498,7 @@ static int ovl_set_or_remove_acl(struct dentry *dentry, struct inode *inode,
old_cred = ovl_override_creds(dentry->d_sb);
real_acl = vfs_get_acl(mnt_idmap(realpath.mnt), realdentry,
acl_name);
- revert_creds(old_cred);
+ ovl_revert_creds(old_cred);
if (IS_ERR(real_acl)) {
err = PTR_ERR(real_acl);
goto out;
@@ -523,7 +523,7 @@ static int ovl_set_or_remove_acl(struct dentry *dentry, struct inode *inode,
err = ovl_do_set_acl(ofs, realdentry, acl_name, acl);
else
err = ovl_do_remove_acl(ofs, realdentry, acl_name);
- revert_creds(old_cred);
+ ovl_revert_creds(old_cred);
ovl_drop_write(dentry);
/* copy c/mtime */
@@ -600,7 +600,7 @@ static int ovl_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
old_cred = ovl_override_creds(inode->i_sb);
err = realinode->i_op->fiemap(realinode, fieinfo, start, len);
- revert_creds(old_cred);
+ ovl_revert_creds(old_cred);
return err;
}
@@ -616,8 +616,13 @@ static int ovl_security_fileattr(const struct path *realpath, struct fileattr *f
struct file *file;
unsigned int cmd;
int err;
+ unsigned int flags;
+
+ flags = O_RDONLY;
+ if (force_o_largefile())
+ flags |= O_LARGEFILE;
- file = dentry_open(realpath, O_RDONLY, current_cred());
+ file = dentry_open(realpath, flags, current_cred());
if (IS_ERR(file))
return PTR_ERR(file);
@@ -671,7 +676,7 @@ int ovl_fileattr_set(struct mnt_idmap *idmap,
err = ovl_set_protattr(inode, upperpath.dentry, fa);
if (!err)
err = ovl_real_fileattr_set(&upperpath, fa);
- revert_creds(old_cred);
+ ovl_revert_creds(old_cred);
ovl_drop_write(dentry);
/*
@@ -733,7 +738,7 @@ int ovl_fileattr_get(struct dentry *dentry, struct fileattr *fa)
old_cred = ovl_override_creds(inode->i_sb);
err = ovl_real_fileattr_get(&realpath, fa);
ovl_fileattr_prot_flags(inode, fa);
- revert_creds(old_cred);
+ ovl_revert_creds(old_cred);
return err;
}