summaryrefslogtreecommitdiff
path: root/fs/overlayfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/overlayfs')
-rw-r--r--fs/overlayfs/copy_up.c22
-rw-r--r--fs/overlayfs/dir.c10
-rw-r--r--fs/overlayfs/inode.c2
-rw-r--r--fs/overlayfs/super.c2
4 files changed, 34 insertions, 2 deletions
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index 807951cb438c..3f803b3a1f82 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -105,6 +105,13 @@ retry:
goto retry;
}
+ error = security_inode_copy_up_xattr(name);
+ if (error < 0 && error != -EOPNOTSUPP)
+ break;
+ if (error == 1) {
+ error = 0;
+ continue; /* Discard */
+ }
error = vfs_setxattr(new, name, value, size, 0);
if (error)
break;
@@ -248,6 +255,8 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
struct dentry *upper = NULL;
umode_t mode = stat->mode;
int err;
+ const struct cred *old_creds = NULL;
+ struct cred *new_creds = NULL;
newdentry = ovl_lookup_temp(workdir, dentry);
err = PTR_ERR(newdentry);
@@ -260,10 +269,23 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
if (IS_ERR(upper))
goto out1;
+ err = security_inode_copy_up(dentry, &new_creds);
+ if (err < 0)
+ goto out2;
+
+ if (new_creds)
+ old_creds = override_creds(new_creds);
+
/* Can't properly set mode on creation because of the umask */
stat->mode &= S_IFMT;
err = ovl_create_real(wdir, newdentry, stat, link, NULL, true);
stat->mode = mode;
+
+ if (new_creds) {
+ revert_creds(old_creds);
+ put_cred(new_creds);
+ }
+
if (err)
goto out2;
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index 463a18477a10..3a60e68ec965 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -489,6 +489,15 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
if (override_cred) {
override_cred->fsuid = inode->i_uid;
override_cred->fsgid = inode->i_gid;
+ if (!hardlink) {
+ err = security_dentry_create_files_as(dentry,
+ stat->mode, &dentry->d_name, old_cred,
+ override_cred);
+ if (err) {
+ put_cred(override_cred);
+ goto out_revert_creds;
+ }
+ }
put_cred(override_creds(override_cred));
put_cred(override_cred);
@@ -499,6 +508,7 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
err = ovl_create_over_whiteout(dentry, inode, stat,
link, hardlink);
}
+out_revert_creds:
revert_creds(old_cred);
if (!err) {
struct inode *realinode = d_inode(ovl_dentry_upper(dentry));
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index b4c35594d9d8..c18d6a4ff456 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -53,7 +53,7 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
* inode_newsize_ok() will always check against MAX_LFS_FILESIZE and not
* check for a swapfile (which this won't be anyway).
*/
- err = inode_change_ok(dentry->d_inode, attr);
+ err = setattr_prepare(dentry, attr);
if (err)
return err;
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index f170114481f7..7e3f0127fc1a 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -1320,7 +1320,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
sb->s_xattr = ovl_xattr_handlers;
sb->s_root = root_dentry;
sb->s_fs_info = ufs;
- sb->s_flags |= MS_POSIXACL;
+ sb->s_flags |= MS_POSIXACL | MS_NOREMOTELOCK;
return 0;