diff options
author | hujianyang <hujianyang@huawei.com> | 2015-01-05 23:52:13 -0500 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2015-01-08 08:47:20 -0500 |
commit | 2f83fd8c2849a388082f30d755a75c1e67c4643b (patch) | |
tree | 09ed1bd07d358487a7a7f3ed3ac863422c2eabdc /fs/overlayfs/super.c | |
parent | 2b7a8f36f092a7855f6438cd42d6990394f450fa (diff) |
ovl: Fix kernel panic while mounting overlayfs
The function ovl_fill_super() in recently multi-layer support
version will incorrectly return 0 at error handling path and
then cause kernel panic.
This failure can be reproduced by mounting a overlayfs with
upperdir and workdir in different mounts.
And also, If the memory allocation of *lower_mnt* fail, this
function may return an zero either.
This patch fix this problem by setting *err* to proper error
number before jumping to error handling path.
Signed-off-by: hujianyang <hujianyang@huawei.com>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs/overlayfs/super.c')
-rw-r--r-- | fs/overlayfs/super.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 84f3144e1b33..6ca8ea8cb9b2 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c | |||
@@ -836,6 +836,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) | |||
836 | if (err) | 836 | if (err) |
837 | goto out_put_upperpath; | 837 | goto out_put_upperpath; |
838 | 838 | ||
839 | err = -EINVAL; | ||
839 | if (upperpath.mnt != workpath.mnt) { | 840 | if (upperpath.mnt != workpath.mnt) { |
840 | pr_err("overlayfs: workdir and upperdir must reside under the same mount\n"); | 841 | pr_err("overlayfs: workdir and upperdir must reside under the same mount\n"); |
841 | goto out_put_workpath; | 842 | goto out_put_workpath; |
@@ -894,12 +895,14 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) | |||
894 | } | 895 | } |
895 | } | 896 | } |
896 | 897 | ||
898 | err = -ENOMEM; | ||
897 | ufs->lower_mnt = kcalloc(numlower, sizeof(struct vfsmount *), GFP_KERNEL); | 899 | ufs->lower_mnt = kcalloc(numlower, sizeof(struct vfsmount *), GFP_KERNEL); |
898 | if (ufs->lower_mnt == NULL) | 900 | if (ufs->lower_mnt == NULL) |
899 | goto out_put_workdir; | 901 | goto out_put_workdir; |
900 | for (i = 0; i < numlower; i++) { | 902 | for (i = 0; i < numlower; i++) { |
901 | struct vfsmount *mnt = clone_private_mount(&stack[i]); | 903 | struct vfsmount *mnt = clone_private_mount(&stack[i]); |
902 | 904 | ||
905 | err = PTR_ERR(mnt); | ||
903 | if (IS_ERR(mnt)) { | 906 | if (IS_ERR(mnt)) { |
904 | pr_err("overlayfs: failed to clone lowerpath\n"); | 907 | pr_err("overlayfs: failed to clone lowerpath\n"); |
905 | goto out_put_lower_mnt; | 908 | goto out_put_lower_mnt; |