diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2014-04-01 17:08:43 +0200 |
---|---|---|
committer | Alex Shi <alex.shi@linaro.org> | 2015-04-17 15:39:11 +0800 |
commit | c3ae3e8840e6b555949cda895d885ad91c5e3f24 (patch) | |
tree | 542cc75cc12523f7c11329559b4d69f34cab9ac9 /security | |
parent | 5371fcd46e9276f4216e329ba2714d595a384a1f (diff) |
vfs: add cross-rename
If flags contain RENAME_EXCHANGE then exchange source and destination files.
There's no restriction on the type of the files; e.g. a directory can be
exchanged with a symlink.
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: J. Bruce Fields <bfields@redhat.com>
(cherry picked from commit da1ce0670c14d8380e423a3239e562a1dc15fa9e)
Signed-off-by: Alex Shi <alex.shi@linaro.org>
Diffstat (limited to 'security')
-rw-r--r-- | security/security.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/security/security.c b/security/security.c index 284fbc99aa9d..8b774f362a3d 100644 --- a/security/security.c +++ b/security/security.c @@ -439,6 +439,14 @@ int security_path_rename(struct path *old_dir, struct dentry *old_dentry, if (unlikely(IS_PRIVATE(old_dentry->d_inode) || (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) return 0; + + if (flags & RENAME_EXCHANGE) { + int err = security_ops->path_rename(new_dir, new_dentry, + old_dir, old_dentry); + if (err) + return err; + } + return security_ops->path_rename(old_dir, old_dentry, new_dir, new_dentry); } @@ -531,6 +539,14 @@ int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, if (unlikely(IS_PRIVATE(old_dentry->d_inode) || (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) return 0; + + if (flags & RENAME_EXCHANGE) { + int err = security_ops->inode_rename(new_dir, new_dentry, + old_dir, old_dentry); + if (err) + return err; + } + return security_ops->inode_rename(old_dir, old_dentry, new_dir, new_dentry); } |