From: Viacheslav Dubeyko <slava@dubeyko.com>
To: "Kullanılmıyor Pasif" <guvenlik@noroxi.com>,
linux-fsdevel@vger.kernel.org
Cc: glaubitz@physik.fu-berlin.de, frank.li@vivo.com,
linux-kernel@vger.kernel.org
Subject: Re: hfsplus: possible recursive locking on extents_lock during unlink/truncate
Date: Wed, 30 Sep 2026 20:49:44 -0700 [thread overview]
Message-ID: <8dfb90a2751df30f76ab5130960591a57c51be4d.camel@dubeyko.com> (raw)
In-Reply-To: <CAHfT-UBFPgXcYu+2sS8bg12GC0LvXpAkVqrSg9N8BzEhUBAO8Q@mail.gmail.com>
On Thu, 2026-10-01 at 02:58 +0400, Kullanılmıyor Pasif wrote:
> # hfsplus: lockdep "possible recursive locking" on extents_lock
> during unlink/truncate
>
> **Reporter:** Noroxi (Mahmut Emin Kurhan <guvenlik@noroxi.com>)
> **Subsystem:** fs/hfsplus
> **Class:** lockdep false-positive (possible recursive locking) — CWE-
> 667-ish
> **Severity:** low — lockdep splat while mounting/using a crafted HFS+
> image. Analysis
> below indicates this is a missing lock-nesting annotation, NOT a real
> runtime
> deadlock (the two locks are different inodes of the same lock class,
> acquired in a
> fixed order). No memory corruption.
> **Status:** analysis from source; observed under syzkaller
> (kmemleak/lockdep) fuzzing
> of HFS+ image mounts. No standalone reproducer extracted yet.
>
> ## lockdep report
>
> ```
> WARNING: possible recursive locking detected
> syz.3.60/2437 is trying to acquire lock:
> (&HFSPLUS_I(inode)->extents_lock){+.+.}, at: hfsplus_get_block+...
> fs/hfsplus/extents.c:264
> but task is already holding lock:
> (&HFSPLUS_I(inode)->extents_lock){+.+.}, at:
> hfsplus_file_truncate+... fs/hfsplus/extents.c:579
> May be due to missing lock nesting notation
> ```
>
> ## Call chain (from the report stack)
>
> ```
> hfsplus_unlink fs/hfsplus/dir.c:420
> hfsplus_delete_inode fs/hfsplus/inode.c:553
> hfsplus_file_truncate fs/hfsplus/extents.c:579 <--
> mutex_lock(inode A ->extents_lock)
> hfsplus_free_extents fs/hfsplus/extents.c:364
> hfsplus_block_free fs/hfsplus/bitmap.c:185 <-- reads
> the allocation bitmap file
> block_read_full_folio fs/buffer.c
> hfsplus_get_block fs/hfsplus/extents.c:264 <--
> mutex_lock(inode B ->extents_lock)
> ```
>
> ## Analysis (why this is annotation, not a real deadlock)
>
> - **inode A** = the regular file being unlinked/truncated.
> - **inode B** = the **allocation bitmap file** (`sbi->alloc_file`):
> `hfsplus_block_free()`
> reads a page of the allocation file, which goes through `-
> >get_block` and locks the
> allocation file's own `extents_lock`.
> - The two lock addresses in the report differ, so these are two
> *different* inode
> instances of the *same* lock class (`extents_lock`). lockdep flags
> this as
> "recursive" and itself notes "May be due to missing lock nesting
> notation".
> - The acquisition order is fixed: a regular file's `extents_lock` is
> taken first (in
> truncate/extend), then the allocation file's `extents_lock` while
> freeing/allocating
> blocks. There is no reverse path (the allocation file's block I/O
> does not take a
> regular file's `extents_lock`), so no real ABBA/self-deadlock
> exists.
>
> ## Suggested fix direction
>
> hfsplus already solves the identical problem for the B-tree
> `tree_lock` via
> `hfsplus_btree_lock_class()` (fs/hfsplus/hfsplus_fs.h), which returns
> a distinct
> lockdep subclass per tree CNID and is used with
> `mutex_lock_nested()`.
>
> The same pattern applied to `extents_lock` would resolve this: assign
> a distinct
> lockdep subclass to the special-inode `extents_lock` (at least the
> allocation file,
> and for completeness the attributes/catalog files) and take it with
> `mutex_lock_nested(&hip->extents_lock,
> hfsplus_extents_lock_class(inode))` at the five
> lock sites (extents.c:153,264,457,579 and xattr.c:267). Regular files
> keep the default
> subclass, so a genuine regular-file-vs-regular-file recursion would
> still be detected.
>
> We can provide a candidate patch if useful; deferring the exact
> subclass scheme to the
> maintainers since the lock design is yours.
>
> ## Disclosure
> Normal fs bug report (not a security embargo). To:
> linux-fsdevel@vger.kernel.org;
> Cc: Viacheslav Dubeyko, John Paul Adrian Glaubitz, Yangtao Li, linux-
> kernel.
>
> ## Credit
> Found by Noroxi via coverage-guided fuzzing (syzkaller) of HFS+ image
> mounts.
Please, send the formal patch and we can start the regular review and
discussion.
Thanks,
Slava.
next parent reply other threads:[~2026-10-01 3:49 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CAHfT-UBFPgXcYu+2sS8bg12GC0LvXpAkVqrSg9N8BzEhUBAO8Q@mail.gmail.com>
2026-10-01 3:49 ` Viacheslav Dubeyko [this message]
2026-10-01 9:52 ` [PATCH] hfsplus: annotate extents_lock nesting to silence lockdep false positive Mahmut Emin Kurhan
2026-10-01 21:38 ` Viacheslav Dubeyko
2026-10-01 21:53 ` [PATCH v2] " Mahmut Emin Kurhan
2026-10-02 18:10 ` Viacheslav Dubeyko
[not found] ` <CAHfT-UCvvYX+24tQnBDGm5=_QgApsNnDJ5GpjeqMXvHgFSXj9w@mail.gmail.com>
2026-10-02 20:19 ` Viacheslav Dubeyko
2026-10-02 21:16 ` [PATCH v3] " Mahmut Emin Kurhan
2026-10-05 19:32 ` Viacheslav Dubeyko
2026-10-02 19:52 ` [PATCH v2] " Mahmut Emin Kurhan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8dfb90a2751df30f76ab5130960591a57c51be4d.camel@dubeyko.com \
--to=slava@dubeyko.com \
--cc=frank.li@vivo.com \
--cc=glaubitz@physik.fu-berlin.de \
--cc=guvenlik@noroxi.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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®