diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2014-04-01 11:08:43 -0400 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2014-04-01 11:08:43 -0400 |
commit | da1ce0670c14d8380e423a3239e562a1dc15fa9e (patch) | |
tree | 146ea4ac0fbf5550db8e65a59ddc7c668b68db76 /security | |
parent | 4fd699ae3fbca2ac760137e1d26f98a105f59f05 (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>
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, | |||
439 | if (unlikely(IS_PRIVATE(old_dentry->d_inode) || | 439 | if (unlikely(IS_PRIVATE(old_dentry->d_inode) || |
440 | (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) | 440 | (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) |
441 | return 0; | 441 | return 0; |
442 | |||
443 | if (flags & RENAME_EXCHANGE) { | ||
444 | int err = security_ops->path_rename(new_dir, new_dentry, | ||
445 | old_dir, old_dentry); | ||
446 | if (err) | ||
447 | return err; | ||
448 | } | ||
449 | |||
442 | return security_ops->path_rename(old_dir, old_dentry, new_dir, | 450 | return security_ops->path_rename(old_dir, old_dentry, new_dir, |
443 | new_dentry); | 451 | new_dentry); |
444 | } | 452 | } |
@@ -531,6 +539,14 @@ int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
531 | if (unlikely(IS_PRIVATE(old_dentry->d_inode) || | 539 | if (unlikely(IS_PRIVATE(old_dentry->d_inode) || |
532 | (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) | 540 | (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) |
533 | return 0; | 541 | return 0; |
542 | |||
543 | if (flags & RENAME_EXCHANGE) { | ||
544 | int err = security_ops->inode_rename(new_dir, new_dentry, | ||
545 | old_dir, old_dentry); | ||
546 | if (err) | ||
547 | return err; | ||
548 | } | ||
549 | |||
534 | return security_ops->inode_rename(old_dir, old_dentry, | 550 | return security_ops->inode_rename(old_dir, old_dentry, |
535 | new_dir, new_dentry); | 551 | new_dir, new_dentry); |
536 | } | 552 | } |