* [PATCH] virtiofs: validate fixed-output response length
@ 2026-10-04 12:34 sungbyeongchan
2026-10-04 12:55 ` Greg Kroah-Hartman
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: sungbyeongchan @ 2026-10-04 12:34 UTC (permalink / raw)
To: German Maglione, Vivek Goyal, Stefan Hajnoczi, Miklos Szeredi
Cc: Eugenio Pérez, virtualization, fuse-devel, linux-fsdevel,
linux-kernel, Greg Kroah-Hartman
A short successful virtiofs response can leave the fixed-output
portion of the request argument buffer unwritten. The completion path
nevertheless copies the full declared output to the request destination,
allowing stale allocator contents to reach callers such as
fuse_statfs().
Require successful fixed-output responses to contain their complete
declared output. Continue to permit a shorter final argument only for
out_argvar requests, and do not copy output arguments from error
replies.
A header-only FUSE_STATFS success returned stale fields in nine of
nine calls across three boots. The patched kernel rejected the short
response in three boots and preserved complete replies and existing
error controls.
Fixes: a62a8ef9d97d ("virtio-fs: add virtiofs filesystem")
Signed-off-by: sungbyeongchan <tjdqudcks0424@naver.com>
---
fs/fuse/virtio_fs.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index f15e516ebcb5c..288848f23e7ec 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -730,6 +730,10 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
unsigned int num_out;
unsigned int i;
+ /* Error replies contain only the output header. */
+ if (req->out.h.error)
+ goto out;
+
remaining = req->out.h.len - sizeof(req->out.h);
num_in = args->in_numargs - args->in_pages;
num_out = args->out_numargs - args->out_pages;
@@ -755,6 +759,7 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
if (args->out_argvar)
args->out_args[args->out_numargs - 1].size = remaining;
+out:
kfree(req->argbuf);
req->argbuf = NULL;
}
@@ -762,7 +767,9 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
/* Verify that the server properly follows the FUSE protocol */
static bool virtio_fs_verify_response(struct fuse_req *req, unsigned int len)
{
+ struct fuse_args *args = req->args;
struct fuse_out_header *oh = &req->out.h;
+ unsigned int expected;
if (len < sizeof(*oh)) {
pr_warn("virtio-fs: response too short (%u)\n", len);
@@ -777,6 +784,25 @@ static bool virtio_fs_verify_response(struct fuse_req *req, unsigned int len)
oh->unique, req->in.h.unique);
return false;
}
+
+ if (oh->error) {
+ if (len != sizeof(*oh)) {
+ pr_warn("virtio-fs: error response too long (%u)\n", len);
+ return false;
+ }
+ return true;
+ }
+
+ expected = sizeof(*oh) +
+ fuse_len_args(args->out_numargs, args->out_args);
+ if (len > expected ||
+ (len < expected &&
+ (!args->out_argvar ||
+ expected - len > args->out_args[args->out_numargs - 1].size))) {
+ pr_warn("virtio-fs: invalid response length (%u, expected %u)\n",
+ len, expected);
+ return false;
+ }
return true;
}
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] virtiofs: validate fixed-output response length
2026-10-04 12:34 [PATCH] virtiofs: validate fixed-output response length sungbyeongchan
@ 2026-10-04 12:55 ` Greg Kroah-Hartman
2026-10-04 12:56 ` Greg Kroah-Hartman
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-04 12:55 UTC (permalink / raw)
To: sungbyeongchan
Cc: German Maglione, Vivek Goyal, Stefan Hajnoczi, Miklos Szeredi,
Eugenio Pérez, virtualization, fuse-devel, linux-fsdevel,
linux-kernel
On Sun, Oct 04, 2026 at 09:34:05PM +0900, sungbyeongchan wrote:
> A short successful virtiofs response can leave the fixed-output
> portion of the request argument buffer unwritten. The completion path
> nevertheless copies the full declared output to the request destination,
> allowing stale allocator contents to reach callers such as
> fuse_statfs().
>
> Require successful fixed-output responses to contain their complete
> declared output. Continue to permit a shorter final argument only for
> out_argvar requests, and do not copy output arguments from error
> replies.
>
> A header-only FUSE_STATFS success returned stale fields in nine of
> nine calls across three boots. The patched kernel rejected the short
> response in three boots and preserved complete replies and existing
> error controls.
>
> Fixes: a62a8ef9d97d ("virtio-fs: add virtiofs filesystem")
> Signed-off-by: sungbyeongchan <tjdqudcks0424@naver.com>
> ---
> fs/fuse/virtio_fs.c | 26 ++++++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
> diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
> index f15e516ebcb5c..288848f23e7ec 100644
> --- a/fs/fuse/virtio_fs.c
> +++ b/fs/fuse/virtio_fs.c
> @@ -730,6 +730,10 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
> unsigned int num_out;
> unsigned int i;
>
> + /* Error replies contain only the output header. */
> + if (req->out.h.error)
> + goto out;
> +
> remaining = req->out.h.len - sizeof(req->out.h);
> num_in = args->in_numargs - args->in_pages;
> num_out = args->out_numargs - args->out_pages;
> @@ -755,6 +759,7 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
> if (args->out_argvar)
> args->out_args[args->out_numargs - 1].size = remaining;
>
> +out:
> kfree(req->argbuf);
> req->argbuf = NULL;
> }
> @@ -762,7 +767,9 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
> /* Verify that the server properly follows the FUSE protocol */
> static bool virtio_fs_verify_response(struct fuse_req *req, unsigned int len)
> {
> + struct fuse_args *args = req->args;
> struct fuse_out_header *oh = &req->out.h;
> + unsigned int expected;
>
> if (len < sizeof(*oh)) {
> pr_warn("virtio-fs: response too short (%u)\n", len);
> @@ -777,6 +784,25 @@ static bool virtio_fs_verify_response(struct fuse_req *req, unsigned int len)
> oh->unique, req->in.h.unique);
> return false;
> }
> +
> + if (oh->error) {
> + if (len != sizeof(*oh)) {
> + pr_warn("virtio-fs: error response too long (%u)\n", len);
> + return false;
> + }
> + return true;
> + }
> +
> + expected = sizeof(*oh) +
> + fuse_len_args(args->out_numargs, args->out_args);
> + if (len > expected ||
> + (len < expected &&
> + (!args->out_argvar ||
> + expected - len > args->out_args[args->out_numargs - 1].size))) {
> + pr_warn("virtio-fs: invalid response length (%u, expected %u)\n",
> + len, expected);
why let remote connections spam the kernel log? And you don't need the
"prefix" of virtio-fs for pr_*() calls if it is working properly.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] virtiofs: validate fixed-output response length
2026-10-04 12:34 [PATCH] virtiofs: validate fixed-output response length sungbyeongchan
2026-10-04 12:55 ` Greg Kroah-Hartman
@ 2026-10-04 12:56 ` Greg Kroah-Hartman
2026-10-04 13:04 ` Michael S. Tsirkin
2026-10-04 14:48 ` [PATCH v2] " Byeongchan Sung
3 siblings, 0 replies; 5+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-04 12:56 UTC (permalink / raw)
To: sungbyeongchan
Cc: German Maglione, Vivek Goyal, Stefan Hajnoczi, Miklos Szeredi,
Eugenio Pérez, virtualization, fuse-devel, linux-fsdevel,
linux-kernel
On Sun, Oct 04, 2026 at 09:34:05PM +0900, sungbyeongchan wrote:
> A short successful virtiofs response can leave the fixed-output
> portion of the request argument buffer unwritten. The completion path
> nevertheless copies the full declared output to the request destination,
> allowing stale allocator contents to reach callers such as
> fuse_statfs().
>
> Require successful fixed-output responses to contain their complete
> declared output. Continue to permit a shorter final argument only for
> out_argvar requests, and do not copy output arguments from error
> replies.
>
> A header-only FUSE_STATFS success returned stale fields in nine of
> nine calls across three boots. The patched kernel rejected the short
> response in three boots and preserved complete replies and existing
> error controls.
>
> Fixes: a62a8ef9d97d ("virtio-fs: add virtiofs filesystem")
> Signed-off-by: sungbyeongchan <tjdqudcks0424@naver.com>
> ---
> fs/fuse/virtio_fs.c | 26 ++++++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
Hi,
This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him
a patch that has triggered this response. He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created. Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.
You are receiving this message because of the following common error(s)
as indicated below:
- It looks like you did not use your "real" name for the patch on either
the Signed-off-by: line, or the From: line (both of which have to
match). Please read the kernel file,
Documentation/process/submitting-patches.rst for how to do this
correctly.
- You have marked a patch with a "Fixes:" tag for a commit that is in an
older released kernel, yet you do not have a cc: stable line in the
signed-off-by area at all, which means that the patch will not be
applied to any older kernel releases. To properly fix this, please
follow the documented rules in the
Documentation/process/stable-kernel-rules.rst file for how to resolve
this.
If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.
thanks,
greg k-h's patch email bot
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] virtiofs: validate fixed-output response length
2026-10-04 12:34 [PATCH] virtiofs: validate fixed-output response length sungbyeongchan
2026-10-04 12:55 ` Greg Kroah-Hartman
2026-10-04 12:56 ` Greg Kroah-Hartman
@ 2026-10-04 13:04 ` Michael S. Tsirkin
2026-10-04 14:48 ` [PATCH v2] " Byeongchan Sung
3 siblings, 0 replies; 5+ messages in thread
From: Michael S. Tsirkin @ 2026-10-04 13:04 UTC (permalink / raw)
To: sungbyeongchan
Cc: German Maglione, Vivek Goyal, Stefan Hajnoczi, Miklos Szeredi,
Eugenio Pérez, virtualization, fuse-devel, linux-fsdevel,
linux-kernel, Greg Kroah-Hartman
On Sun, Oct 04, 2026 at 09:34:05PM +0900, sungbyeongchan wrote:
> A short successful virtiofs response can leave the fixed-output
> portion of the request argument buffer unwritten. The completion path
> nevertheless copies the full declared output to the request destination,
> allowing stale allocator contents to reach callers such as
> fuse_statfs().
>
> Require successful fixed-output responses to contain their complete
> declared output. Continue to permit a shorter final argument only for
> out_argvar requests, and do not copy output arguments from error
> replies.
>
> A header-only FUSE_STATFS success returned stale fields in nine of
> nine calls across three boots. The patched kernel rejected the short
> response in three boots and preserved complete replies and existing
> error controls.
>
> Fixes: a62a8ef9d97d ("virtio-fs: add virtiofs filesystem")
> Signed-off-by: sungbyeongchan <tjdqudcks0424@naver.com>
> ---
> fs/fuse/virtio_fs.c | 26 ++++++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
> diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
> index f15e516ebcb5c..288848f23e7ec 100644
> --- a/fs/fuse/virtio_fs.c
> +++ b/fs/fuse/virtio_fs.c
> @@ -730,6 +730,10 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
> unsigned int num_out;
> unsigned int i;
>
> + /* Error replies contain only the output header. */
> + if (req->out.h.error)
> + goto out;
> +
> remaining = req->out.h.len - sizeof(req->out.h);
> num_in = args->in_numargs - args->in_pages;
> num_out = args->out_numargs - args->out_pages;
> @@ -755,6 +759,7 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
> if (args->out_argvar)
> args->out_args[args->out_numargs - 1].size = remaining;
>
> +out:
> kfree(req->argbuf);
> req->argbuf = NULL;
> }
> @@ -762,7 +767,9 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
> /* Verify that the server properly follows the FUSE protocol */
> static bool virtio_fs_verify_response(struct fuse_req *req, unsigned int len)
> {
> + struct fuse_args *args = req->args;
> struct fuse_out_header *oh = &req->out.h;
> + unsigned int expected;
>
> if (len < sizeof(*oh)) {
> pr_warn("virtio-fs: response too short (%u)\n", len);
> @@ -777,6 +784,25 @@ static bool virtio_fs_verify_response(struct fuse_req *req, unsigned int len)
> oh->unique, req->in.h.unique);
> return false;
> }
> +
> + if (oh->error) {
> + if (len != sizeof(*oh)) {
> + pr_warn("virtio-fs: error response too long (%u)\n", len);
> + return false;
> + }
> + return true;
> + }
What if oh->error > 0? Won't we still have the uninitialized problem
then if callers treat it as success? E.g. the ioctl path seems to do
this... Maybe reject that? Or oh->error <= -512 for that matter, as
fuse_send_ioctl does?
> +
> + expected = sizeof(*oh) +
> + fuse_len_args(args->out_numargs, args->out_args);
> + if (len > expected ||
> + (len < expected &&
> + (!args->out_argvar ||
> + expected - len > args->out_args[args->out_numargs - 1].size))) {
> + pr_warn("virtio-fs: invalid response length (%u, expected %u)\n",
> + len, expected);
> + return false;
> + }
> return true;
> }
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2] virtiofs: validate fixed-output response length
2026-10-04 12:34 [PATCH] virtiofs: validate fixed-output response length sungbyeongchan
` (2 preceding siblings ...)
2026-10-04 13:04 ` Michael S. Tsirkin
@ 2026-10-04 14:48 ` Byeongchan Sung
3 siblings, 0 replies; 5+ messages in thread
From: Byeongchan Sung @ 2026-10-04 14:48 UTC (permalink / raw)
To: German Maglione, Vivek Goyal, Stefan Hajnoczi, Miklos Szeredi
Cc: Eugenio Pérez, Michael S . Tsirkin, virtualization,
fuse-devel, linux-fsdevel, linux-kernel, stable,
Greg Kroah-Hartman
A short successful virtiofs response can leave the fixed-output
portion of the request argument buffer unwritten. The completion path
nevertheless copies the full declared output to the request destination,
allowing stale allocator contents to reach callers such as
fuse_statfs().
Require successful fixed-output responses to contain their complete
declared output. Continue to permit a shorter final argument only for
out_argvar requests. Reject positive and internal restart error values,
require valid error replies to be header-only, and do not copy output
arguments from error replies.
A header-only FUSE_STATFS success returned stale fields in nine of
nine calls across three boots. The fixed kernel rejected the short
response and preserved complete replies, valid error replies, and
variable-output controls.
Fixes: a62a8ef9d97d ("virtio-fs: add virtiofs filesystem")
Cc: stable@vger.kernel.org
Signed-off-by: Byeongchan Sung <tjdqudcks0424@naver.com>
---
Changes in v2:
- Reject positive and internal restart error values.
- Require error replies to be header-only.
- Rate-limit malformed-response warnings.
- Rely on the existing FUSE pr_fmt prefix.
- Add Cc: stable@vger.kernel.org.
- Use the author's real name consistently.
fs/fuse/virtio_fs.c | 43 ++++++++++++++++++++++++++++++++++++++-----
1 file changed, 38 insertions(+), 5 deletions(-)
diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index f15e516ebcb5c..fffbe08d9114a 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -4,6 +4,8 @@
* Copyright (C) 2018 Red Hat, Inc.
*/
+#include "fuse_i.h"
+
#include <linux/fs.h>
#include <linux/dax.h>
#include <linux/pci.h>
@@ -20,7 +22,6 @@
#include <linux/cleanup.h>
#include <linux/uio.h>
#include "dev.h"
-#include "fuse_i.h"
#include "fuse_dev_i.h"
/* Used to help calculate the FUSE connection's max_pages limit for a request's
@@ -730,6 +731,10 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
unsigned int num_out;
unsigned int i;
+ /* Error replies contain only the output header. */
+ if (req->out.h.error)
+ goto out;
+
remaining = req->out.h.len - sizeof(req->out.h);
num_in = args->in_numargs - args->in_pages;
num_out = args->out_numargs - args->out_pages;
@@ -755,6 +760,7 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
if (args->out_argvar)
args->out_args[args->out_numargs - 1].size = remaining;
+out:
kfree(req->argbuf);
req->argbuf = NULL;
}
@@ -762,19 +768,46 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
/* Verify that the server properly follows the FUSE protocol */
static bool virtio_fs_verify_response(struct fuse_req *req, unsigned int len)
{
+ struct fuse_args *args = req->args;
struct fuse_out_header *oh = &req->out.h;
+ unsigned int expected;
if (len < sizeof(*oh)) {
- pr_warn("virtio-fs: response too short (%u)\n", len);
+ pr_warn_ratelimited("response too short (%u)\n", len);
return false;
}
if (oh->len != len) {
- pr_warn("virtio-fs: oh.len mismatch (%u != %u)\n", oh->len, len);
+ pr_warn_ratelimited("oh.len mismatch (%u != %u)\n",
+ oh->len, len);
return false;
}
if (oh->unique != req->in.h.unique) {
- pr_warn("virtio-fs: oh.unique mismatch (%llu != %llu)\n",
- oh->unique, req->in.h.unique);
+ pr_warn_ratelimited("oh.unique mismatch (%llu != %llu)\n",
+ oh->unique, req->in.h.unique);
+ return false;
+ }
+ if (oh->error <= -ERESTARTSYS || oh->error > 0) {
+ pr_warn_ratelimited("invalid error value (%d)\n", oh->error);
+ return false;
+ }
+
+ if (oh->error) {
+ if (len != sizeof(*oh)) {
+ pr_warn_ratelimited("error response too long (%u)\n",
+ len);
+ return false;
+ }
+ return true;
+ }
+
+ expected = sizeof(*oh) +
+ fuse_len_args(args->out_numargs, args->out_args);
+ if (len > expected ||
+ (len < expected &&
+ (!args->out_argvar ||
+ expected - len > args->out_args[args->out_numargs - 1].size))) {
+ pr_warn_ratelimited("invalid response length (%u, expected %u)\n",
+ len, expected);
return false;
}
return true;
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-10-04 14:48 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-04 12:34 [PATCH] virtiofs: validate fixed-output response length sungbyeongchan
2026-10-04 12:55 ` Greg Kroah-Hartman
2026-10-04 12:56 ` Greg Kroah-Hartman
2026-10-04 13:04 ` Michael S. Tsirkin
2026-10-04 14:48 ` [PATCH v2] " Byeongchan Sung
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®