diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2011-06-08 16:53:50 +0200 |
---|---|---|
committer | Linaro CI <john.rigby@linaro.org> | 2012-02-07 22:46:20 +0000 |
commit | 74d86f0d7e27f78d0b0e369187040856a63e485e (patch) | |
tree | 312d6620149b2b0353c6b2a2aa2b686edd5217cf /fs | |
parent | aee1ebfd00f9f4c8529b2c8e493cdff1306f969c (diff) |
UBUNTU: ubuntu: overlayfs -- ovl: fix overlayfs over overlayfs
Overlayfs expects ->permission() to not check for readonliness (which
is normally checked by the VFS) and so not return with -EROFS. This
is not true of some filesystems, notably overlayfs itself.
The following patch should fix this by making sure that if the upper
layer is read-only (such as squashfs) then it will mark overlayfs
read-only too and by making ovl_permission() only return EROFS in the
excpetional case where the upper filesystem became r/o after the
overlay was constructed.
Reported-by: Jordi Pujol <jordipujolp@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Andy Whitcroft <apw@canonical.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/overlayfs/inode.c | 11 | ||||
-rw-r--r-- | fs/overlayfs/super.c | 4 |
2 files changed, 14 insertions, 1 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 289006e8d49..ce39fab84ec 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -90,9 +90,18 @@ int ovl_permission(struct inode *inode, int mask, unsigned int flags) /* * Writes will always be redirected to upper layer, so * ignore lower layer being read-only. + * + * If the overlay itself is read-only then proceed + * with the permission check, don't return EROFS. + * This will only happen if this is the lower layer of + * another overlayfs. + * + * If upper fs becomes read-only after the overlay was + * constructed return EROFS to prevent modification of + * upper layer. */ err = -EROFS; - if (is_upper && IS_RDONLY(realinode) && + if (is_upper && !IS_RDONLY(inode) && IS_RDONLY(realinode) && (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) goto out_dput; diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 7109b45a171..c741b17835a 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -548,6 +548,10 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) goto out_put_upper_mnt; } + /* If the upper fs is r/o, we mark overlayfs r/o too */ + if (ufs->upper_mnt->mnt_sb->s_flags & MS_RDONLY) + sb->s_flags |= MS_RDONLY; + if (!(sb->s_flags & MS_RDONLY)) { err = mnt_want_write(ufs->upper_mnt); if (err) |