#817·btrfs

Reference/memory leaks on common paths: same-directory rename, hard-link query, create_subvol, etc.

Author: xfcyhuangCreated Sep 4, 2026Updated Sep 4, 2026

Audit findings against master @ a0648190 (v1.10). A few of the more reachable leaks; all were verified against the free_fcb/free_fileref/reap_* ownership semantics.

  1. Same-directory rename leaks a fileref reference every time — src/fileinfo.c set_rename_information: related gets a reference (~3136/3139, or from open_fileref at ~3176) but end: only releases it on failure (if (!NT_SUCCESS(Status) && related) free_fileref(related);, ~3255-3256). The cross-directory / cross-subvol callees take ownership via fileref->parent = related, but rename_in_same_directory does not touch parent, so on the success path the reference is never dropped — the directory's fileref/fcb can never be reaped until dismount.

  2. Hard-link query leaks when a parent is marked deleted — src/fileinfo.c fill_in_hard_link_information (~4942) and fill_in_hard_link_full_id_information (~5112): free_fileref(parfr) sits inside the else if (!parfr->deleted) block, so when open_fileref_by_inode succeeds but the parent is deleted, its reference leaks. Also, fill_in_hard_link_full_id_information dereferences fr2->dc->index (~5064) without the fr2->dc && guard its sibling has (~4897) — dummy filerefs have dc == NULL (NULL deref).

  3. create_subvol never frees utf8.Buffer — src/fsctl.c ~838 (allocation) to ~1136-1157 (end): unlike create_snapshot (~732) and mknod (~4159), every exit path leaks it. Any user with FILE_ADD_SUBDIRECTORY on a directory can loop this to drain PagedPool.

  4. open_fileref_child streampart race leaks an fcb reference — src/create.c ~1594-1610: when dc->fileref was set concurrently, duff_fr is freed directly (ExFreeToPagedLookasideList) while the fcb reference taken at ~1582 is never dropped. The non-stream branch handles this correctly (sf2->fcb = fcb at ~1667 + reap_fileref(duff_fr) at ~1688, whose free_fcb balances it).

  5. Mount-failure cleanup — src/btrfs.c mount_vol exit path (~5066-5118) leaks roots/trees/chunks/sys_chunks/dummy_fcb/batch list, and deletes the lookaside lists before reap_fcb runs (so reaped fcbs go back into already-deleted lookasides). Repeatedly mounting a crafted image that fails late drains kernel memory.

There are ~25 more insert_tree_item failure-path leaks in extent-tree.c and a handful in flushthread.c / balance.c / send.c of the same shape (the function does not take ownership of data on failure, but the callers just return) — happy to provide the full list if useful.