Re: [PATCH v3] ovl: fix null pointer when filesystemdoesn'tsupportdirect IO
From: Huang Jianan <hidden>
Date: 2021-09-28 07:01:23
Also in:
linux-fsdevel, lkml
在 2021/9/27 17:38, Miklos Szeredi 写道:
On Wed, Sep 22, 2021 at 04:00:47PM +0200, Miklos Szeredi wrote:quoted
First let's fix the oops: ovl_read_iter()/ovl_write_iter() must check real file's ->direct_IO if IOCB_DIRECT is set in iocb->ki_flags and return -EINVAL if not.And here's that fix. Please test.
This patch can fix the oops. Tested-by: Huang Jianan <redacted> Thanks, Jianan
quoted hunk ↗ jump to hunk
Thanks, Miklos --- From: Miklos Szeredi <redacted> Subject: ovl: fix IOCB_DIRECT if underlying fs doesn't support direct IO Normally the check at open time suffices, but e.g loop device does set IOCB_DIRECT after doing its own checks (which are not sufficent for overlayfs). Make sure we don't call the underlying filesystem read/write method with the IOCB_DIRECT if it's not supported. Reported-by: Huang Jianan <redacted> Fixes: 16914e6fc7e1 ("ovl: add ovl_read_iter()") Cc: <redacted> # v4.19 Signed-off-by: Miklos Szeredi <redacted> --- fs/overlayfs/file.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)--- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c@@ -296,6 +296,12 @@ static ssize_t ovl_read_iter(struct kioc if (ret) return ret; + ret = -EINVAL; + if (iocb->ki_flags & IOCB_DIRECT && + (!real.file->f_mapping->a_ops || + !real.file->f_mapping->a_ops->direct_IO)) + goto out_fdput; + old_cred = ovl_override_creds(file_inode(file)->i_sb); if (is_sync_kiocb(iocb)) { ret = vfs_iter_read(real.file, iter, &iocb->ki_pos,@@ -320,7 +326,7 @@ static ssize_t ovl_read_iter(struct kioc out: revert_creds(old_cred); ovl_file_accessed(file); - +out_fdput: fdput(real); return ret;@@ -349,6 +355,12 @@ static ssize_t ovl_write_iter(struct kio if (ret) goto out_unlock; + ret = -EINVAL; + if (iocb->ki_flags & IOCB_DIRECT && + (!real.file->f_mapping->a_ops || + !real.file->f_mapping->a_ops->direct_IO)) + goto out_fdput; + if (!ovl_should_sync(OVL_FS(inode->i_sb))) ifl &= ~(IOCB_DSYNC | IOCB_SYNC);@@ -384,6 +396,7 @@ static ssize_t ovl_write_iter(struct kio } out: revert_creds(old_cred); +out_fdput: fdput(real); out_unlock: