diff options
author | Amir Goldstein <amir73il@gmail.com> | 2017-07-11 08:58:34 -0400 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2017-07-13 16:06:45 -0400 |
commit | ea3dad18dc5f778cfd931311a91a9315aa0065a3 (patch) | |
tree | d2a1a3e51e877eb9c0ad249e5dcf4c17a33f01a5 /fs | |
parent | 8fc646b44385ff0a9853f6590497e43049eeb311 (diff) |
ovl: mark parent impure on ovl_link()
When linking a file with copy up origin into a new parent, mark the
new parent dir "impure".
Fixes: ee1d6d37b6b8 ("ovl: mark upper dir with type origin entries "impure"")
Cc: <stable@vger.kernel.org> # v4.12
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/overlayfs/dir.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 641d9ee97f91..48b70e6490f3 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c | |||
@@ -481,17 +481,30 @@ out_cleanup: | |||
481 | } | 481 | } |
482 | 482 | ||
483 | static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, | 483 | static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, |
484 | struct cattr *attr, struct dentry *hardlink) | 484 | struct cattr *attr, struct dentry *hardlink, |
485 | bool origin) | ||
485 | { | 486 | { |
486 | int err; | 487 | int err; |
487 | const struct cred *old_cred; | 488 | const struct cred *old_cred; |
488 | struct cred *override_cred; | 489 | struct cred *override_cred; |
490 | struct dentry *parent = dentry->d_parent; | ||
489 | 491 | ||
490 | err = ovl_copy_up(dentry->d_parent); | 492 | err = ovl_copy_up(parent); |
491 | if (err) | 493 | if (err) |
492 | return err; | 494 | return err; |
493 | 495 | ||
494 | old_cred = ovl_override_creds(dentry->d_sb); | 496 | old_cred = ovl_override_creds(dentry->d_sb); |
497 | |||
498 | /* | ||
499 | * When linking a file with copy up origin into a new parent, mark the | ||
500 | * new parent dir "impure". | ||
501 | */ | ||
502 | if (origin) { | ||
503 | err = ovl_set_impure(parent, ovl_dentry_upper(parent)); | ||
504 | if (err) | ||
505 | goto out_revert_creds; | ||
506 | } | ||
507 | |||
495 | err = -ENOMEM; | 508 | err = -ENOMEM; |
496 | override_cred = prepare_creds(); | 509 | override_cred = prepare_creds(); |
497 | if (override_cred) { | 510 | if (override_cred) { |
@@ -550,7 +563,7 @@ static int ovl_create_object(struct dentry *dentry, int mode, dev_t rdev, | |||
550 | inode_init_owner(inode, dentry->d_parent->d_inode, mode); | 563 | inode_init_owner(inode, dentry->d_parent->d_inode, mode); |
551 | attr.mode = inode->i_mode; | 564 | attr.mode = inode->i_mode; |
552 | 565 | ||
553 | err = ovl_create_or_link(dentry, inode, &attr, NULL); | 566 | err = ovl_create_or_link(dentry, inode, &attr, NULL, false); |
554 | if (err) | 567 | if (err) |
555 | iput(inode); | 568 | iput(inode); |
556 | 569 | ||
@@ -609,7 +622,8 @@ static int ovl_link(struct dentry *old, struct inode *newdir, | |||
609 | inode = d_inode(old); | 622 | inode = d_inode(old); |
610 | ihold(inode); | 623 | ihold(inode); |
611 | 624 | ||
612 | err = ovl_create_or_link(new, inode, NULL, ovl_dentry_upper(old)); | 625 | err = ovl_create_or_link(new, inode, NULL, ovl_dentry_upper(old), |
626 | ovl_type_origin(old)); | ||
613 | if (err) | 627 | if (err) |
614 | iput(inode); | 628 | iput(inode); |
615 | 629 | ||