diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2011-06-08 16:53:50 +0200 |
---|---|---|
committer | John Rigby <john.rigby@linaro.org> | 2011-09-23 08:54:04 -0600 |
commit | 7210c35b7859fd9c694a1b42eeca168c686a1602 (patch) | |
tree | 91845e6bed7e1091c130020f37d8382b0ce965b0 /fs | |
parent | 05d55b6fb5d3cd32053f5ea8eafaa8d9977dab09 (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) |