diff options
| -rw-r--r-- | fs/overlayfs/copy_up.c | 3 | ||||
| -rw-r--r-- | fs/overlayfs/dir.c | 9 | ||||
| -rw-r--r-- | fs/overlayfs/super.c | 10 |
3 files changed, 17 insertions, 5 deletions
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 24f640441bd9..84d693d37428 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c | |||
| @@ -299,6 +299,9 @@ int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, | |||
| 299 | struct cred *override_cred; | 299 | struct cred *override_cred; |
| 300 | char *link = NULL; | 300 | char *link = NULL; |
| 301 | 301 | ||
| 302 | if (WARN_ON(!workdir)) | ||
| 303 | return -EROFS; | ||
| 304 | |||
| 302 | ovl_path_upper(parent, &parentpath); | 305 | ovl_path_upper(parent, &parentpath); |
| 303 | upperdir = parentpath.dentry; | 306 | upperdir = parentpath.dentry; |
| 304 | 307 | ||
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 2578a0c0677d..692ceda3bc21 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c | |||
| @@ -222,6 +222,9 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry, | |||
| 222 | struct kstat stat; | 222 | struct kstat stat; |
| 223 | int err; | 223 | int err; |
| 224 | 224 | ||
| 225 | if (WARN_ON(!workdir)) | ||
| 226 | return ERR_PTR(-EROFS); | ||
| 227 | |||
| 225 | err = ovl_lock_rename_workdir(workdir, upperdir); | 228 | err = ovl_lock_rename_workdir(workdir, upperdir); |
| 226 | if (err) | 229 | if (err) |
| 227 | goto out; | 230 | goto out; |
| @@ -322,6 +325,9 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, | |||
| 322 | struct dentry *newdentry; | 325 | struct dentry *newdentry; |
| 323 | int err; | 326 | int err; |
| 324 | 327 | ||
| 328 | if (WARN_ON(!workdir)) | ||
| 329 | return -EROFS; | ||
| 330 | |||
| 325 | err = ovl_lock_rename_workdir(workdir, upperdir); | 331 | err = ovl_lock_rename_workdir(workdir, upperdir); |
| 326 | if (err) | 332 | if (err) |
| 327 | goto out; | 333 | goto out; |
| @@ -506,6 +512,9 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, bool is_dir) | |||
| 506 | struct dentry *opaquedir = NULL; | 512 | struct dentry *opaquedir = NULL; |
| 507 | int err; | 513 | int err; |
| 508 | 514 | ||
| 515 | if (WARN_ON(!workdir)) | ||
| 516 | return -EROFS; | ||
| 517 | |||
| 509 | if (is_dir) { | 518 | if (is_dir) { |
| 510 | if (OVL_TYPE_MERGE_OR_LOWER(ovl_path_type(dentry))) { | 519 | if (OVL_TYPE_MERGE_OR_LOWER(ovl_path_type(dentry))) { |
| 511 | opaquedir = ovl_check_empty_and_clear(dentry); | 520 | opaquedir = ovl_check_empty_and_clear(dentry); |
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 5f0d1993e6e3..bf8537c7f455 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c | |||
| @@ -529,7 +529,7 @@ static int ovl_remount(struct super_block *sb, int *flags, char *data) | |||
| 529 | { | 529 | { |
| 530 | struct ovl_fs *ufs = sb->s_fs_info; | 530 | struct ovl_fs *ufs = sb->s_fs_info; |
| 531 | 531 | ||
| 532 | if (!(*flags & MS_RDONLY) && !ufs->upper_mnt) | 532 | if (!(*flags & MS_RDONLY) && (!ufs->upper_mnt || !ufs->workdir)) |
| 533 | return -EROFS; | 533 | return -EROFS; |
| 534 | 534 | ||
| 535 | return 0; | 535 | return 0; |
| @@ -925,9 +925,10 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) | |||
| 925 | ufs->workdir = ovl_workdir_create(ufs->upper_mnt, workpath.dentry); | 925 | ufs->workdir = ovl_workdir_create(ufs->upper_mnt, workpath.dentry); |
| 926 | err = PTR_ERR(ufs->workdir); | 926 | err = PTR_ERR(ufs->workdir); |
| 927 | if (IS_ERR(ufs->workdir)) { | 927 | if (IS_ERR(ufs->workdir)) { |
| 928 | pr_err("overlayfs: failed to create directory %s/%s\n", | 928 | pr_warn("overlayfs: failed to create directory %s/%s (errno: %i); mounting read-only\n", |
| 929 | ufs->config.workdir, OVL_WORKDIR_NAME); | 929 | ufs->config.workdir, OVL_WORKDIR_NAME, -err); |
| 930 | goto out_put_upper_mnt; | 930 | sb->s_flags |= MS_RDONLY; |
| 931 | ufs->workdir = NULL; | ||
| 931 | } | 932 | } |
| 932 | } | 933 | } |
| 933 | 934 | ||
| @@ -997,7 +998,6 @@ out_put_lower_mnt: | |||
| 997 | kfree(ufs->lower_mnt); | 998 | kfree(ufs->lower_mnt); |
| 998 | out_put_workdir: | 999 | out_put_workdir: |
| 999 | dput(ufs->workdir); | 1000 | dput(ufs->workdir); |
| 1000 | out_put_upper_mnt: | ||
| 1001 | mntput(ufs->upper_mnt); | 1001 | mntput(ufs->upper_mnt); |
| 1002 | out_put_lowerpath: | 1002 | out_put_lowerpath: |
| 1003 | for (i = 0; i < numlower; i++) | 1003 | for (i = 0; i < numlower; i++) |
