diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-04 17:03:05 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-04 17:03:05 -0400 |
| commit | 7df934526c0b3775613502dcd19ab6d2da8cce1e (patch) | |
| tree | 01e6a4ea20c676228f4acefc6ae776d2e52072db /security | |
| parent | 3c83e61e67256e0bb08c46cc2db43b58fd617251 (diff) | |
| parent | bd42998a6bcb9b1708dac9ca9876e3d304c16f3d (diff) | |
Merge branch 'cross-rename' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull renameat2 system call from Miklos Szeredi:
"This adds a new syscall, renameat2(), which is the same as renameat()
but with a flags argument.
The purpose of extending rename is to add cross-rename, a symmetric
variant of rename, which exchanges the two files. This allows
interesting things, which were not possible before, for example
atomically replacing a directory tree with a symlink, etc... This
also allows overlayfs and friends to operate on whiteouts atomically.
Andy Lutomirski also suggested a "noreplace" flag, which disables the
overwriting behavior of rename.
These two flags, RENAME_EXCHANGE and RENAME_NOREPLACE are only
implemented for ext4 as an example and for testing"
* 'cross-rename' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs:
ext4: add cross rename support
ext4: rename: split out helper functions
ext4: rename: move EMLINK check up
ext4: rename: create ext4_renament structure for local vars
vfs: add cross-rename
vfs: lock_two_nondirectories: allow directory args
security: add flags to rename hooks
vfs: add RENAME_NOREPLACE flag
vfs: add renameat2 syscall
vfs: rename: use common code for dir and non-dir
vfs: rename: move d_move() up
vfs: add d_is_dir()
Diffstat (limited to 'security')
| -rw-r--r-- | security/security.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/security/security.c b/security/security.c index 919cad93ac82..8b774f362a3d 100644 --- a/security/security.c +++ b/security/security.c | |||
| @@ -433,11 +433,20 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir, | |||
| 433 | } | 433 | } |
| 434 | 434 | ||
| 435 | int security_path_rename(struct path *old_dir, struct dentry *old_dentry, | 435 | int security_path_rename(struct path *old_dir, struct dentry *old_dentry, |
| 436 | struct path *new_dir, struct dentry *new_dentry) | 436 | struct path *new_dir, struct dentry *new_dentry, |
| 437 | unsigned int flags) | ||
| 437 | { | 438 | { |
| 438 | if (unlikely(IS_PRIVATE(old_dentry->d_inode) || | 439 | if (unlikely(IS_PRIVATE(old_dentry->d_inode) || |
| 439 | (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) | 440 | (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) |
| 440 | 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 | |||
| 441 | return security_ops->path_rename(old_dir, old_dentry, new_dir, | 450 | return security_ops->path_rename(old_dir, old_dentry, new_dir, |
| 442 | new_dentry); | 451 | new_dentry); |
| 443 | } | 452 | } |
| @@ -524,11 +533,20 @@ int security_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
| 524 | } | 533 | } |
| 525 | 534 | ||
| 526 | int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, | 535 | int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, |
| 527 | struct inode *new_dir, struct dentry *new_dentry) | 536 | struct inode *new_dir, struct dentry *new_dentry, |
| 537 | unsigned int flags) | ||
| 528 | { | 538 | { |
| 529 | if (unlikely(IS_PRIVATE(old_dentry->d_inode) || | 539 | if (unlikely(IS_PRIVATE(old_dentry->d_inode) || |
| 530 | (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) | 540 | (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) |
| 531 | 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 | |||
| 532 | return security_ops->inode_rename(old_dir, old_dentry, | 550 | return security_ops->inode_rename(old_dir, old_dentry, |
| 533 | new_dir, new_dentry); | 551 | new_dir, new_dentry); |
| 534 | } | 552 | } |
