From: Greg Kroah-Hartman Date: Mon, 15 Jun 2020 12:32:29 +0000 (+0200) Subject: 5.6-stable patches X-Git-Tag: v5.4.47~111 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b766643dfdfd64d56bea56a83b5d5e225189b12d;p=thirdparty%2Fkernel%2Fstable-queue.git 5.6-stable patches added patches: aio-fix-async-fsync-creds.patch --- diff --git a/queue-5.6/aio-fix-async-fsync-creds.patch b/queue-5.6/aio-fix-async-fsync-creds.patch new file mode 100644 index 00000000000..94ae01742d8 --- /dev/null +++ b/queue-5.6/aio-fix-async-fsync-creds.patch @@ -0,0 +1,73 @@ +From 530f32fc370fd1431ea9802dbc53ab5601dfccdb Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Thu, 14 May 2020 16:44:24 +0200 +Subject: aio: fix async fsync creds + +From: Miklos Szeredi + +commit 530f32fc370fd1431ea9802dbc53ab5601dfccdb upstream. + +Avi Kivity reports that on fuse filesystems running in a user namespace +asyncronous fsync fails with EOVERFLOW. + +The reason is that f_ops->fsync() is called with the creds of the kthread +performing aio work instead of the creds of the process originally +submitting IOCB_CMD_FSYNC. + +Fuse sends the creds of the caller in the request header and it needs to +translate the uid and gid into the server's user namespace. Since the +kthread is running in init_user_ns, the translation will fail and the +operation returns an error. + +It can be argued that fsync doesn't actually need any creds, but just +zeroing out those fields in the header (as with requests that currently +don't take creds) is a backward compatibility risk. + +Instead of working around this issue in fuse, solve the core of the problem +by calling the filesystem with the proper creds. + +Reported-by: Avi Kivity +Tested-by: Giuseppe Scrivano +Fixes: c9582eb0ff7d ("fuse: Fail all requests with invalid uids or gids") +Cc: stable@vger.kernel.org # 4.18+ +Signed-off-by: Miklos Szeredi +Reviewed-by: Christoph Hellwig +Signed-off-by: Greg Kroah-Hartman + +--- + fs/aio.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/fs/aio.c ++++ b/fs/aio.c +@@ -176,6 +176,7 @@ struct fsync_iocb { + struct file *file; + struct work_struct work; + bool datasync; ++ struct cred *creds; + }; + + struct poll_iocb { +@@ -1589,8 +1590,11 @@ static int aio_write(struct kiocb *req, + static void aio_fsync_work(struct work_struct *work) + { + struct aio_kiocb *iocb = container_of(work, struct aio_kiocb, fsync.work); ++ const struct cred *old_cred = override_creds(iocb->fsync.creds); + + iocb->ki_res.res = vfs_fsync(iocb->fsync.file, iocb->fsync.datasync); ++ revert_creds(old_cred); ++ put_cred(iocb->fsync.creds); + iocb_put(iocb); + } + +@@ -1604,6 +1608,10 @@ static int aio_fsync(struct fsync_iocb * + if (unlikely(!req->file->f_op->fsync)) + return -EINVAL; + ++ req->creds = prepare_creds(); ++ if (!req->creds) ++ return -ENOMEM; ++ + req->datasync = datasync; + INIT_WORK(&req->work, aio_fsync_work); + schedule_work(&req->work); diff --git a/queue-5.6/series b/queue-5.6/series index 4a69e1996de..324b82b07bd 100644 --- a/queue-5.6/series +++ b/queue-5.6/series @@ -43,3 +43,4 @@ scsi-target-remove-boilerplate-code.patch scsi-target-fix-hang-when-multiple-threads-try-to-de.patch drm-amd-display-remove-invalid-dc_is_hw_initialized-.patch drm-amd-display-not-doing-optimize-bandwidth-if-flip.patch +aio-fix-async-fsync-creds.patch