From b10b85fe5149ee8b39fbbf86095b303632dde2cd Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 27 Jul 2022 16:31:30 +0200 Subject: ovl: warn if trusted xattr creation fails When mounting overlayfs in an unprivileged user namespace, trusted xattr creation will fail. This will lead to failures in some file operations, e.g. in the following situation: mkdir lower upper work merged mkdir lower/directory mount -toverlay -olowerdir=lower,upperdir=upper,workdir=work none merged rmdir merged/directory mkdir merged/directory The last mkdir will fail: mkdir: cannot create directory 'merged/directory': Input/output error The cause for these failures is currently extremely non-obvious and hard to debug. Hence, warn the user and suggest using the userxattr mount option, if it is not already supplied and xattr creation fails during the self-check. Reported-by: Alois Wohlschlager Signed-off-by: Miklos Szeredi --- fs/overlayfs/super.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'fs/overlayfs') diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 1ce5c9698393..4c2096130209 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -1418,11 +1418,12 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs, */ err = ovl_setxattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE, "0", 1); if (err) { + pr_warn("failed to set xattr on upper\n"); ofs->noxattr = true; if (ofs->config.index || ofs->config.metacopy) { ofs->config.index = false; ofs->config.metacopy = false; - pr_warn("upper fs does not support xattr, falling back to index=off,metacopy=off.\n"); + pr_warn("...falling back to index=off,metacopy=off.\n"); } /* * xattr support is required for persistent st_ino. @@ -1430,8 +1431,10 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs, */ if (ofs->config.xino == OVL_XINO_AUTO) { ofs->config.xino = OVL_XINO_OFF; - pr_warn("upper fs does not support xattr, falling back to xino=off.\n"); + pr_warn("...falling back to xino=off.\n"); } + if (err == -EPERM && !ofs->config.userxattr) + pr_info("try mounting with 'userxattr' option\n"); err = 0; } else { ovl_removexattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE); -- cgit v1.2.3 From 9c5dd8034e3544d139c2531e58d3ca41bbf343dd Mon Sep 17 00:00:00 2001 From: Yang Li Date: Wed, 1 Jun 2022 10:28:14 +0800 Subject: ovl: fix some kernel-doc comments Remove warnings found by running scripts/kernel-doc, which is caused by using 'make W=1'. fs/overlayfs/super.c:311: warning: Function parameter or member 'dentry' not described in 'ovl_statfs' fs/overlayfs/super.c:311: warning: Excess function parameter 'sb' description in 'ovl_statfs' fs/overlayfs/super.c:357: warning: Function parameter or member 'm' not described in 'ovl_show_options' fs/overlayfs/super.c:357: warning: Function parameter or member 'dentry' not described in 'ovl_show_options' Reported-by: Abaci Robot Signed-off-by: Yang Li Signed-off-by: Miklos Szeredi --- fs/overlayfs/super.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs/overlayfs') diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 4c2096130209..963de480b400 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -301,7 +301,7 @@ static int ovl_sync_fs(struct super_block *sb, int wait) /** * ovl_statfs - * @sb: The overlayfs super block + * @dentry: The dentry to query * @buf: The struct kstatfs to fill in with stats * * Get the filesystem statistics. As writes always target the upper layer @@ -349,6 +349,8 @@ static inline int ovl_xino_def(void) /** * ovl_show_options + * @m: the seq_file handle + * @dentry: The dentry to query * * Prints the mount options for a given superblock. * Returns zero; does not fail. -- cgit v1.2.3 From ded536561a3674327dfa4bb389085705cae22b8a Mon Sep 17 00:00:00 2001 From: Yang Xu Date: Thu, 28 Jul 2022 10:49:24 +0800 Subject: ovl: improve ovl_get_acl() if POSIX ACL support is off Provide a proper stub for the !CONFIG_FS_POSIX_ACL case. Signed-off-by: Yang Xu Signed-off-by: Miklos Szeredi --- fs/overlayfs/inode.c | 4 +++- fs/overlayfs/overlayfs.h | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'fs/overlayfs') diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 492eddeb481f..beef5e2ff563 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -454,13 +454,14 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) return res; } +#ifdef CONFIG_FS_POSIX_ACL struct posix_acl *ovl_get_acl(struct inode *inode, int type, bool rcu) { struct inode *realinode = ovl_inode_real(inode); const struct cred *old_cred; struct posix_acl *acl; - if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !IS_POSIXACL(realinode)) + if (!IS_POSIXACL(realinode)) return NULL; if (rcu) @@ -472,6 +473,7 @@ struct posix_acl *ovl_get_acl(struct inode *inode, int type, bool rcu) return acl; } +#endif int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags) { diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 4f34b7e02eee..3d8de16a76e9 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -599,7 +599,13 @@ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name, int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, void *value, size_t size); ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); + +#ifdef CONFIG_FS_POSIX_ACL struct posix_acl *ovl_get_acl(struct inode *inode, int type, bool rcu); +#else +#define ovl_get_acl NULL +#endif + int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags); bool ovl_is_private_xattr(struct super_block *sb, const char *name); -- cgit v1.2.3 From dd524b7f317de8d31d638cbfdc7be4cf9b770e42 Mon Sep 17 00:00:00 2001 From: Jiachen Zhang Date: Thu, 28 Jul 2022 19:49:15 +0800 Subject: ovl: drop WARN_ON() dentry is NULL in ovl_encode_fh() Some code paths cannot guarantee the inode have any dentry alias. So WARN_ON() all !dentry may flood the kernel logs. For example, when an overlayfs inode is watched by inotifywait (1), and someone is trying to read the /proc/$(pidof inotifywait)/fdinfo/INOTIFY_FD, at that time if the dentry has been reclaimed by kernel (such as echo 2 > /proc/sys/vm/drop_caches), there will be a WARN_ON(). The printed call stack would be like: ? show_mark_fhandle+0xf0/0xf0 show_mark_fhandle+0x4a/0xf0 ? show_mark_fhandle+0xf0/0xf0 ? seq_vprintf+0x30/0x50 ? seq_printf+0x53/0x70 ? show_mark_fhandle+0xf0/0xf0 inotify_fdinfo+0x70/0x90 show_fdinfo.isra.4+0x53/0x70 seq_show+0x130/0x170 seq_read+0x153/0x440 vfs_read+0x94/0x150 ksys_read+0x5f/0xe0 do_syscall_64+0x59/0x1e0 entry_SYSCALL_64_after_hwframe+0x44/0xa9 So let's drop WARN_ON() to avoid kernel log flooding. Reported-by: Hongbo Yin Signed-off-by: Jiachen Zhang Signed-off-by: Tianci Zhang Fixes: 8ed5eec9d6c4 ("ovl: encode pure upper file handles") Cc: # v4.16 Signed-off-by: Miklos Szeredi --- fs/overlayfs/export.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/overlayfs') diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c index 2eada97bbd23..e065a5b9a442 100644 --- a/fs/overlayfs/export.c +++ b/fs/overlayfs/export.c @@ -259,7 +259,7 @@ static int ovl_encode_fh(struct inode *inode, u32 *fid, int *max_len, return FILEID_INVALID; dentry = d_find_any_alias(inode); - if (WARN_ON(!dentry)) + if (!dentry) return FILEID_INVALID; bytes = ovl_dentry_to_fid(ofs, dentry, fid, buflen); -- cgit v1.2.3 From 4f1196288dfb6fc63e28e585392f2df3b8a63388 Mon Sep 17 00:00:00 2001 From: William Dean Date: Fri, 29 Jul 2022 09:57:26 +0800 Subject: ovl: fix spelling mistakes fix follow spelling misktakes: decendant ==> descendant indentify ==> identify underlaying ==> underlying Reported-by: Hacash Robot Signed-off-by: William Dean Signed-off-by: Miklos Szeredi --- fs/overlayfs/namei.c | 4 ++-- fs/overlayfs/super.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'fs/overlayfs') diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index 65c4346a5b43..69dc577974f8 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -42,7 +42,7 @@ static int ovl_check_redirect(struct path *path, struct ovl_lookup_data *d, * One of the ancestor path elements in an absolute path * lookup in ovl_lookup_layer() could have been opaque and * that will stop further lookup in lower layers (d->stop=true) - * But we have found an absolute redirect in decendant path + * But we have found an absolute redirect in descendant path * element and that should force continue lookup in lower * layers (reset d->stop). */ @@ -648,7 +648,7 @@ static int ovl_get_index_name_fh(struct ovl_fh *fh, struct qstr *name) * If the index dentry for a copy up origin inode is positive, but points * to an inode different than the upper inode, then either the upper inode * has been copied up and not indexed or it was indexed, but since then - * index dir was cleared. Either way, that index cannot be used to indentify + * index dir was cleared. Either way, that index cannot be used to identify * the overlay inode. */ int ovl_get_index_name(struct ovl_fs *ofs, struct dentry *origin, diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 963de480b400..ba16c88b7c9b 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -2057,7 +2057,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) sb->s_stack_depth = 0; sb->s_maxbytes = MAX_LFS_FILESIZE; atomic_long_set(&ofs->last_ino, 1); - /* Assume underlaying fs uses 32bit inodes unless proven otherwise */ + /* Assume underlying fs uses 32bit inodes unless proven otherwise */ if (ofs->config.xino != OVL_XINO_OFF) { ofs->xino_mode = BITS_PER_LONG - 32; if (!ofs->xino_mode) { -- cgit v1.2.3