All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] 9pfs: fix deep path truncation in V9fsPath
@ 2026-04-28  7:46 Jia Jia
  2026-04-28  8:21 ` Please ignore my " Jia Jia
  2026-04-30  8:57 ` Christian Schoenebeck
  0 siblings, 2 replies; 5+ messages in thread
From: Jia Jia @ 2026-04-28  7:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: Christian Schoenebeck, Greg Kurz, qemu-stable

V9fsPath.size tracks the length of backend path data. Storing it in a
uint16_t truncates local backend paths longer than 65535 bytes, so later
path copies can end up much smaller than the string data they are
supposed to describe.

A guest can reach this with normal 9p filesystem operations by creating
and walking a sufficiently deep directory tree on the local backend. On
an ASan build, calling readdir() in that deep directory aborts the host
process with:

  ERROR: AddressSanitizer: heap-buffer-overflow
    #0 __interceptor_strrchr
    #1 g_path_get_dirname
    #2 local_lstat
    #3 v9fs_co_lstat
    #4 v9fs_getattr

Fix this by storing V9fsPath lengths in size_t.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3358
Cc: qemu-stable@nongnu.org
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
---
Runtime reproducer:
  confirmed on current master (11.0.50) with an x86_64 ASan build and a
  local 9p backend

  guest actions:
    - mount the 9p share
    - create a 260-level directory tree with 255-byte names
    - walk back to the deepest directory
    - call readdir()

  host abort:
    ERROR: AddressSanitizer: heap-buffer-overflow
      #0 __interceptor_strrchr
      #1 g_path_get_dirname
      #2 local_lstat
      #3 v9fs_co_lstat
      #4 v9fs_getattr

 fsdev/file-op-9p.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
index b85c9934def..e8d0661c4b5 100644
--- a/fsdev/file-op-9p.h
+++ b/fsdev/file-op-9p.h
@@ -112,7 +112,7 @@ struct FsContext {
 };
 
 struct V9fsPath {
-    uint16_t size;
+    size_t size;
     char *data;
 };
 P9ARRAY_DECLARE_TYPE(V9fsPath);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Please ignore my [PATCH] 9pfs: fix deep path truncation in V9fsPath
  2026-04-28  7:46 [PATCH] 9pfs: fix deep path truncation in V9fsPath Jia Jia
@ 2026-04-28  8:21 ` Jia Jia
  2026-04-30  8:57 ` Christian Schoenebeck
  1 sibling, 0 replies; 5+ messages in thread
From: Jia Jia @ 2026-04-28  8:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Christian Schoenebeck, Greg Kurz, qemu-stable

Hi,

Please ignore my [PATCH] 9pfs: fix deep path truncation in V9fsPath.

Sorry. This issue has already been submitted, and the existing GitLab
report already includes a concrete fix proposal:
https://gitlab.com/qemu-project/qemu/-/work_items/3358

Please ignore my patch, and sorry for the noise.

Thanks,
Jia Jia


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] 9pfs: fix deep path truncation in V9fsPath
  2026-04-28  7:46 [PATCH] 9pfs: fix deep path truncation in V9fsPath Jia Jia
  2026-04-28  8:21 ` Please ignore my " Jia Jia
@ 2026-04-30  8:57 ` Christian Schoenebeck
  2026-04-30 12:52   ` Jia Jia
  1 sibling, 1 reply; 5+ messages in thread
From: Christian Schoenebeck @ 2026-04-30  8:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Greg Kurz, qemu-stable, Jia Jia

On Tuesday, 28 April 2026 09:46:14 CEST Jia Jia wrote:
> V9fsPath.size tracks the length of backend path data. Storing it in a
> uint16_t truncates local backend paths longer than 65535 bytes, so later
> path copies can end up much smaller than the string data they are
> supposed to describe.
> 
> A guest can reach this with normal 9p filesystem operations by creating
> and walking a sufficiently deep directory tree on the local backend. On
> an ASan build, calling readdir() in that deep directory aborts the host
> process with:
> 
>   ERROR: AddressSanitizer: heap-buffer-overflow
>     #0 __interceptor_strrchr
>     #1 g_path_get_dirname
>     #2 local_lstat
>     #3 v9fs_co_lstat
>     #4 v9fs_getattr
> 
> Fix this by storing V9fsPath lengths in size_t.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3358
> Cc: qemu-stable@nongnu.org
> Signed-off-by: Jia Jia <physicalmtea@gmail.com>
> ---

Hi Jia, thanks for looking at this issue!

> Runtime reproducer:
>   confirmed on current master (11.0.50) with an x86_64 ASan build and a
>   local 9p backend
> 
>   guest actions:
>     - mount the 9p share
>     - create a 260-level directory tree with 255-byte names
>     - walk back to the deepest directory
>     - call readdir()
> 
>   host abort:
>     ERROR: AddressSanitizer: heap-buffer-overflow
>       #0 __interceptor_strrchr
>       #1 g_path_get_dirname
>       #2 local_lstat
>       #3 v9fs_co_lstat
>       #4 v9fs_getattr
> 
>  fsdev/file-op-9p.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
> index b85c9934def..e8d0661c4b5 100644
> --- a/fsdev/file-op-9p.h
> +++ b/fsdev/file-op-9p.h
> @@ -112,7 +112,7 @@ struct FsContext {
>  };
> 
>  struct V9fsPath {
> -    uint16_t size;
> +    size_t size;
>      char *data;
>  };
>  P9ARRAY_DECLARE_TYPE(V9fsPath);

I fear it is not that simple. Just changing this data type would only move the 
problem and furthermore turn a small OOB into a giant OOB: g_vasprintf() 
(called by v9fs_path_sprintf()) has as return type gint -> int, and 
v9fs_path_sprintf() returns -1 on error, and this change would then implicitly 
cast -1 to a giant unsigned value.

AFAICS the only way for truly fixing this is by getting rid of dragging full 
paths around with FIDs in general, which would be a massive change though.

On short term I only see a possible mitigation: adding error handling to 
v9fs_path_sprintf(), and for FIDs where v9fs_fix_path() fails, making the fids 
inaccessible for good (i.e. immediately closing those FIDs).

/Christian




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] 9pfs: fix deep path truncation in V9fsPath
  2026-04-30  8:57 ` Christian Schoenebeck
@ 2026-04-30 12:52   ` Jia Jia
  2026-05-04 10:30     ` Christian Schoenebeck
  0 siblings, 1 reply; 5+ messages in thread
From: Jia Jia @ 2026-04-30 12:52 UTC (permalink / raw)
  To: Christian Schoenebeck; +Cc: qemu-devel, Greg Kurz, qemu-stable

Hi Christian,

I agree. Just widening V9fsPath.size is not a real fix; given that
g_vasprintf() returns a signed value and v9fs_path_sprintf() can return -1,
my change could indeed make the failure case worse by turning that into a
huge unsigned size.

I also realized afterwards that this issue had already been reported and that
my patch was essentially repeating the same incomplete direction. That is why
I sent the follow-up asking people to ignore it:
https://lore.kernel.org/all/20260428082151.3234483-1-physicalmtea@gmail.com/

If I understood your suggestion correctly, the short-term mitigation would be
roughly:

  - make v9fs_path_sprintf() fail on both g_vasprintf() failure and overlong
    results;
  - propagate that error through callers such as local_name_to_path();
  - make v9fs_fix_path() return an error as well;
  - and if a live fid path cannot be rebuilt during rename/fixup, clunk or
    otherwise invalidate that fid immediately instead of leaving it reachable
    with invalid path state.

So this is not just a local check in v9fs_path_sprintf(), but also error
propagation plus fid invalidation on fixup failure.

Sorry for the noise, and thanks for the clarification.

Thanks,
Jia Jia


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] 9pfs: fix deep path truncation in V9fsPath
  2026-04-30 12:52   ` Jia Jia
@ 2026-05-04 10:30     ` Christian Schoenebeck
  0 siblings, 0 replies; 5+ messages in thread
From: Christian Schoenebeck @ 2026-05-04 10:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-devel, Greg Kurz, qemu-stable, Jia Jia

On Thursday, 30 April 2026 14:52:41 CEST Jia Jia wrote:
[...]
> If I understood your suggestion correctly, the short-term mitigation would
> be roughly:
> 
>   - make v9fs_path_sprintf() fail on both g_vasprintf() failure and overlong
> results;
>   - propagate that error through callers such as local_name_to_path();
>   - make v9fs_fix_path() return an error as well;
>   - and if a live fid path cannot be rebuilt during rename/fixup, clunk or
>     otherwise invalidate that fid immediately instead of leaving it
> reachable with invalid path state.

Yes, that's roughly what I had in mind as short-term mitigation. Additionally 
I would suggest calling error_report_once() somewhere, as it would be an 
unusual incident that should be logged.

> So this is not just a local check in v9fs_path_sprintf(), but also error
> propagation plus fid invalidation on fixup failure.

Right, unfortunately I don't see an easier way to address this. E.g. one might 
think to just add a max. path length check when creating a new file/dir, which 
would fix the reported vector, but then it could still be triggered by moving 
a dir into a subdir, and the moved dir could have a deep directory structure, 
so one simple path length check would not be sufficient.

/Christian




^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-05-04 10:31 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-28  7:46 [PATCH] 9pfs: fix deep path truncation in V9fsPath Jia Jia
2026-04-28  8:21 ` Please ignore my " Jia Jia
2026-04-30  8:57 ` Christian Schoenebeck
2026-04-30 12:52   ` Jia Jia
2026-05-04 10:30     ` Christian Schoenebeck

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.