diff options
Diffstat (limited to 'fs/overlayfs')
-rw-r--r-- | fs/overlayfs/copy_up.c | 22 | ||||
-rw-r--r-- | fs/overlayfs/dir.c | 10 | ||||
-rw-r--r-- | fs/overlayfs/inode.c | 2 | ||||
-rw-r--r-- | fs/overlayfs/super.c | 2 |
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; |