From: Yung-Tse Cheng <[email protected]> [ Upstream commit 6af3330ec5d5fb8c06c04eb520a71cf73ea5a765 ]
virtio_fs_setup_vqs() allocates fs->vqs and fs->mq_map before calling virtio_find_vqs(). If virtio_find_vqs() fails, the error path frees both pointers and returns an error to virtio_fs_probe(). virtio_fs_probe() then drops the last kobject reference, and virtio_fs_ktype_release() frees fs->vqs and fs->mq_map again. This leaves dangling pointers in struct virtio_fs and can trigger a double-free during probe failure cleanup. Set fs->vqs and fs->mq_map to NULL immediately after kfree() in the virtio_fs_setup_vqs() error path so that the later kobject release sees an uninitialized state and kfree(NULL) becomes harmless. This can be reproduced when a broken virtio-fs device advertises more request queues than the transport actually provides. In that case virtio_find_vqs() fails while setting up the extra queue, and the probe path reaches the double-free cleanup sequence. Signed-off-by: Yung-Tse Cheng <[email protected]> Signed-off-by: Miklos Szeredi <[email protected]> Signed-off-by: Sasha Levin <[email protected]> --- LLM Generated explanations, may be completely bogus: ## Phase 1: Commit Message Forensics ### Step 1.1: Subject Line **Record:** `[virtio-fs] [avoid] double-free on failed queue setup` — explicit bug fix in the virtio-fs driver error path during virtqueue setup. ### Step 1.2: Tags **Record:** - **Signed-off-by:** Yung-Tse Cheng `<[email protected]>` (author) - **Signed-off-by:** Miklos Szeredi `<[email protected]>` (FUSE/virtio-fs maintainer) - No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, Acked-by:, Link:, or Cc: stable tags Notable: maintainer Signed-off-by is a strong quality signal. ### Step 1.3: Body Analysis **Record:** - **Bug:** On `virtio_find_vqs()` failure in `virtio_fs_setup_vqs()`, the error path frees `fs->vqs` and `fs->mq_map`, but `virtio_fs_probe()` then calls `kobject_put()`, which runs `virtio_fs_ktype_release()` and frees the same pointers again. - **Symptom:** Double-free and dangling pointers during probe-failure cleanup; potential kernel crash / memory corruption. - **Trigger:** Broken virtio-fs device advertising more request queues than the transport actually provides. - **Root cause:** Missing NULL assignment after `kfree()` in the setup error path, so the kobject release path cannot tell memory was already freed. ### Step 1.4: Hidden Bug Fix? **Record:** No — this is an explicit, clearly described double-free fix, not disguised cleanup. --- ## Phase 2: Diff Analysis ### Step 2.1: Inventory **Record:** - **File:** `fs/fuse/virtio_fs.c` (+2 lines, 0 removed) - **Function:** `virtio_fs_setup_vqs()` - **Scope:** Single-file, surgical fix (2 lines) ### Step 2.2: Code Flow Change **Record:** - **Hunk (error path in `virtio_fs_setup_vqs()`):** - **Before:** On failure (`ret != 0`), `kfree(fs->vqs)` and `kfree(fs->mq_map)` leave dangling pointers in `struct virtio_fs`. - **After:** Same frees, then `fs->vqs = NULL` and `fs->mq_map = NULL`, so later `virtio_fs_ktype_release()` does harmless `kfree(NULL)`. ### Step 2.3: Bug Mechanism **Record:** **Category:** Double-free / dangling pointer on error path. **Mechanism:** `virtio_fs_setup_vqs()` and `virtio_fs_ktype_release()` both free the same allocations without coordinating ownership transfer. ### Step 2.4: Fix Quality **Record:** Obviously correct, minimal, standard kernel pattern. Regression risk is very low — only affects the failure path and makes cleanup idempotent. --- ## Phase 3: Git History Investigation ### Step 3.1: Blame **Record:** - `kfree(fs->vqs)` in error path: Stefan Hajnoczi, 2018-06-12 (`a62a8ef9d97da2`) - `if (ret) { ... kfree(fs->mq_map); }` wrapper: Peter-Jan Gootzen, 2024-05-01 (`529395d2ae6456`, "virtio-fs: add multi-queue support") - The **double-free mechanism** was introduced when kobject lifecycle landed in `virtio_fs_ktype_release()` — commit `a8f62f50b4e4e` (2024-02-12, "virtiofs: export filesystem tags through sysfs"). That commit is an ancestor of this tree and of `v6.18`. ### Step 3.2: Fixes: Tag **Record:** N/A — no Fixes: tag present. ### Step 3.3: Related File History **Record:** Recent `virtio_fs.c` activity includes other probe/cleanup fixes (e.g. `c014021253d77` incorrect fsvq kobj check). No related fix for this double-free is present. The candidate fix is not yet in this tree. ### Step 3.4: Author Context **Record:** Yung-Tse Cheng has no prior commits in this checkout. Miklos Szeredi is the FUSE maintainer and signed off on the patch. ### Step 3.5: Dependencies **Record:** Standalone, 2-line fix. No series dependencies. `git apply --check` succeeds cleanly against the local tree. --- ## Phase 4: Mailing List and External Research ### Step 4.1: Original Discussion **Record:** `b4 dig -c` failed (commit not in local tree). Web search found the patch at [mail-archive.com](https://www.mail- archive.com/[email protected]/msg2622149.html) and [Patchew]( https://patchew.org/linux/[email protected]/). Posted 2026-04-06 by Yung-Tse Cheng. Standalone 1-patch series. Lore fetch timed out; no review-thread details retrieved. ### Step 4.2: Reviewers **Record:** From Spinics archive: To: virtio-fs maintainers (gmaglione, vgoyal, stefanha, miklos). Cc: virtualization@, linux-fsdevel@, linux- kernel@. Appropriate maintainers were included. ### Step 4.3: Bug Report **Record:** No external bug report or syzbot link. Author describes reproducible scenario with a misconfigured/broken virtio-fs device. ### Step 4.4: Related Patches **Record:** Standalone fix, not part of a multi-patch series. ### Step 4.5: Stable List History **Record:** No stable-list discussion found. UNVERIFIED due to lore access failure. --- ## Phase 5: Code Semantic Analysis ### Step 5.1: Key Functions **Record:** `virtio_fs_setup_vqs()`, `virtio_fs_ktype_release()`, `virtio_fs_probe()` ### Step 5.2: Callers **Record:** - `virtio_fs_setup_vqs()` — called only from `virtio_fs_probe()` (line 1133) - `virtio_fs_ktype_release()` — kobject `.release` callback, invoked via `kobject_put()` from `virtio_fs_probe()` error path (line 1160) and normal teardown paths ### Step 5.3: Callees **Record:** `kcalloc()`, `virtio_find_vqs()`, `kfree()`, `kobject_put()` — standard probe allocation/cleanup. ### Step 5.4: Reachability **Record:** ``` virtio device probe → virtio_fs_probe() → virtio_fs_setup_vqs() [fails] → error path kfree(vqs, mq_map) → out: kobject_put() → virtio_fs_ktype_release() [double-free without fix] ``` Reachable during virtio-fs device enumeration when queue setup fails (broken device, ENOMEM, or `virtio_find_vqs()` failure). Not a syscall path directly, but triggered during driver probe on systems with virtio- fs enabled. ### Step 5.5: Similar Patterns **Record:** No `fs->vqs = NULL` or `fs->mq_map = NULL` anywhere in current `virtio_fs.c`. The dangling-pointer pattern is unique to this error path. --- ## Phase 6: Cross-Reference Against Local Tree ### Step 6.1: Buggy Code Present? **Record:** **YES.** Local tree is **v6.18.44** (`git describe HEAD` → `v6.18.44-1-g2736c32da98b9`). Current code at lines 989–992 frees without NULLing: ```989:992:fs/fuse/virtio_fs.c if (ret) { kfree(fs->vqs); kfree(fs->mq_map); } ``` And `virtio_fs_ktype_release()` at lines 195–196 frees the same pointers again. Fix is not yet applied. ### Step 6.2: Backport Complications **Record:** Clean apply — `git apply --check` passed with exit code 0. No conflicts expected. ### Step 6.3: Related Fixes Already Present? **Record:** None. `git log -S 'fs->mq_map = NULL'` returned no results. No grep matches for NULL assignments. --- ## Phase 7: Subsystem Context ### Step 7.1: Subsystem **Record:** `fs/fuse/virtio_fs.c` — virtio-fs driver (FUSE over virtio). **Criticality: IMPORTANT** — affects virtualization/virtio-fs users, not universal core kernel, but probe failures can crash the host/VM. ### Step 7.2: Activity **Record:** Actively maintained; recent virtio-fs and fuse fixes in this tree. --- ## Phase 8: Impact and Risk Assessment ### Step 8.1: Who Is Affected **Record:** Systems with `CONFIG_VIRTIO_FS` enabled (module or built-in) where virtio-fs device probe fails during queue setup — VMs with virtio- fs, hosts exporting virtio-fs, or broken/malicious virtio device configurations. ### Step 8.2: Trigger Conditions **Record:** - `virtio_find_vqs()` failure (e.g. device advertises more queues than transport supports) - Also any error path through `out:` label with `ret != 0` after `fs->vqs`/`fs->mq_map` were allocated (including ENOMEM) - Not everyday, but reproducible on probe failure; privileged entity controlling virtio device configuration can trigger it ### Step 8.3: Failure Mode Severity **Record:** **Double-free** → kernel oops, possible memory corruption. **Severity: HIGH** (crash / potential security impact from heap corruption on probe failure). ### Step 8.4: Risk-Benefit **Record:** - **Benefit:** HIGH — prevents crash on legitimate probe failure paths - **Risk:** VERY LOW — 2 lines, error-path only, idempotent cleanup - **Ratio:** Strongly favors backport --- ## Phase 9: Final Synthesis ### Step 9.1: Evidence Summary **FOR backport:** - Real double-free bug with clear mechanism - Reproducible trigger described (broken virtio-fs queue advertisement) - HIGH severity (kernel crash / memory corruption) - Minimal 2-line fix, applies cleanly - FUSE maintainer (Miklos Szeredi) Signed-off-by - Bug present in this 6.18.44 tree since kobject lifecycle (Feb 2024); mq_map added second vector (May 2024) - Standard NULL-after-kfree pattern **AGAINST backport:** - Only triggered on probe failure, not hot path - No syzbot report or CVE - Lore review thread not fully retrieved **UNRESOLVED:** - Whether reviewers explicitly nominated for stable (lore fetch failed) - Whether patch has landed in mainline yet (not in this checkout) ### Step 9.2: Stable Rules Checklist 1. Obviously correct and tested? **PASS** — standard pattern; maintainer SOB; author describes reproduction 2. Fixes a real bug? **PASS** — verified double-free in local code 3. Important issue? **PASS** — double-free on probe failure (HIGH) 4. Small and contained? **PASS** — 2 lines, 1 file 5. No new features/APIs? **PASS** 6. Can apply to local tree? **PASS** — clean apply verified ### Step 9.3: Exception Categories **Record:** None — this is a straight bug fix, not a quirk/ID/DT/build/doc exception. ### Step 9.4: Decision Rationale This tree (6.18.44) contains the buggy code: `virtio_fs_setup_vqs()` frees `fs->vqs` and `fs->mq_map` on error without NULLing them, and `virtio_fs_probe()` unconditionally calls `kobject_put()` which re-frees them in `virtio_fs_ktype_release()`. The fix is minimal, obviously correct, and prevents a kernel crash on a realistic probe-failure path. It fully meets stable kernel criteria. --- ## Verification - [Phase 1] Parsed subject, tags, body from provided commit message - [Phase 1] Confirmed maintainer Signed-off-by: Miklos Szeredi - [Phase 2] Read current `virtio_fs_setup_vqs()` error path (lines 986–993): missing NULL assignments - [Phase 2] Read `virtio_fs_ktype_release()` (lines 191–197): frees same pointers - [Phase 2] Read `virtio_fs_probe()` error path (lines 1158–1161): `kobject_put()` on all failures - [Phase 3] `git describe HEAD`: v6.18.44-1-g2736c32da98b9 - [Phase 3] `git blame -L 989,992`: error-path code from 2018 (vqs) and 2024 (mq_map wrapper) - [Phase 3] `git show 529395d2ae6456`: mq_map kfree added to error path without NULL - [Phase 3] `git show a8f62f50b4e4e`: kobject lifecycle introduced double-free mechanism - [Phase 3] `git merge-base --is-ancestor a8f62f50b4e4e HEAD`: confirmed in tree - [Phase 3] `git merge-base --is-ancestor 529395d2ae6456 HEAD`: confirmed in tree - [Phase 3] `git log -S 'fs->mq_map = NULL'`: no existing fix - [Phase 4] `b4 dig -c df25d4faca41c`: failed (commit not in tree) - [Phase 4] Web search: found patch submission at mail-archive.com and Patchew (2026-04-06) - [Phase 4] Lore direct fetch: timed out — review comments UNVERIFIED - [Phase 5] `grep virtio_fs_setup_vqs`: single caller in `virtio_fs_probe()` - [Phase 5] Traced probe → setup_vqs error → kobject_put → ktype_release call chain - [Phase 6] Confirmed buggy code present at lines 989–992; fix absent (no NULL assignments) - [Phase 6] `git apply --check`: patch applies cleanly (exit 0) - [Phase 7] Read `fs/fuse/Kconfig`: VIRTIO_FS depends on FUSE_FS + VIRTIO - [Phase 8] Assessed severity: double-free on probe failure = HIGH **YES**Those background searches finished and line up with the earlier analysis: - **Author lookup** — No commits from Yung-Tse Cheng / `mes900903` in this 6.18.44 tree; the patch is still a candidate, not merged here. - **Commit message search** — Nothing matching “avoid double-free on failed queue setup” in local history. - **Alternate-fix search** — No other commit in `fs/fuse/` that already fixes this. Together that confirms the bug is present locally and the fix isn’t applied yet. The backport recommendation remains **YES**. fs/fuse/virtio_fs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index b2f6486fe1d56..2b3daa93e299a 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -988,7 +988,9 @@ static int virtio_fs_setup_vqs(struct virtio_device *vdev, kfree(vqs); if (ret) { kfree(fs->vqs); + fs->vqs = NULL; kfree(fs->mq_map); + fs->mq_map = NULL; } return ret; } -- 2.53.0

