All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "John Groves" <john@jagalactic.com>
Cc: linux-cxl@vger.kernel.org
Subject: Re: [PATCH V3 7/9] dax: fix holder_ops race in fs_put_dax()
Date: Sat, 30 May 2026 18:08:58 +0000	[thread overview]
Message-ID: <20260530180859.420861F00893@smtp.kernel.org> (raw)
In-Reply-To: <0100019e79cc1d9e-d39ff70d-4f1d-4a02-8b8e-e01c70272c0c-000000@email.amazonses.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:

New issues:
- [High] The `WARN_ON` in `fs_put_dax()` will falsely trigger during normal filesystem unmount if the DAX device was hot-unplugged.
- [High] Unconditional clear of `holder_ops` in `fs_put_dax()` before validating ownership can corrupt the state of concurrent valid holders.

Pre-existing issues:
- [High] Lockless double-fetch of `dax_dev->holder_ops` in `dax_holder_notify_failure()` can lead to a NULL pointer dereference.
- [High] Missing SRCU synchronization in `fs_put_dax()` allows use-after-free and module use-after-unload during unmount.
- [High] Inode reference leak in `fs_dax_get_by_bdev()` when a concurrent holder already owns the DAX device.
--

commit 182e9ccdc90a15375d69ff8ae0ad8f75bda03aed
Author: John Groves <John@Groves.net>

dax: fix holder_ops race in fs_put_dax()

Clear holder_ops before holder_data so that a concurrent fs_dax_get()
cannot have its newly installed holder_ops overwritten.

> diff --git a/drivers/dax/super.c b/drivers/dax/super.c
> index 25cf99dd9360b..4c56ac2faacdb 100644
> --- a/drivers/dax/super.c
> +++ b/drivers/dax/super.c

[ ... ]

>  void fs_put_dax(struct dax_device *dax_dev, void *holder)
>  {
> -	if (dax_dev && holder &&
> -	    cmpxchg(&dax_dev->holder_data, holder, NULL) == holder)
> -		dax_dev->holder_ops = NULL;
> +	if (dax_dev && holder) {

[ ... ]

> +		WRITE_ONCE(dax_dev->holder_ops, NULL);
[Severity: High]
Could this unconditional write corrupt the state of concurrent valid holders?

By clearing dax_dev->holder_ops unconditionally before checking ownership
with cmpxchg(), a caller passing the wrong holder could inadvertently
overwrite the holder_ops installed by a legitimate subsystem that just
acquired the DAX device.

> +		WARN_ON(cmpxchg(&dax_dev->holder_data, holder, NULL) != holder);
[Severity: High]
Will this WARN_ON falsely trigger during a normal filesystem unmount if the
DAX device was hot-unplugged?

When a DAX device is hot-unplugged, the driver calls kill_dax(), which sets
dax_dev->holder_data = NULL.

If the user subsequently unmounts the filesystem, fs_put_dax() is called, but
the cmpxchg will see NULL instead of the expected holder. This would cause
the WARN_ON to fire and potentially panic systems configured with
panic_on_warn during normal administrative operations.

> +	}
>  	put_dax(dax_dev);
[Severity: High]
This isn't a bug introduced by this patch, but does fs_put_dax() need SRCU
synchronization before returning?

dax_holder_notify_failure() runs asynchronously under the dax_read_lock()
SRCU critical section. Since fs_put_dax() clears the holder registration but
returns immediately without calling synchronize_srcu(&dax_srcu), could a
filesystem unmount proceed, destroying in-memory structures and unloading
the module while the notify_failure callback is still actively executing?

>  }

[Severity: High]
This isn't a bug introduced by this patch, but does fs_dax_get_by_bdev() leak
an inode reference when a concurrent holder already owns the DAX device?

drivers/dax/super.c:fs_dax_get_by_bdev() {
    ...
	else if (holder) {
		if (!cmpxchg(&dax_dev->holder_data, NULL, holder))
			dax_dev->holder_ops = ops;
		else
			dax_dev = NULL;
	}
    ...
}

When a dax_dev is found, its inode reference count is incremented via
igrab(&dax_dev->inode). If cmpxchg() fails because the device is already
held, dax_dev is set to NULL, but the function appears to return without
calling iput(&dax_dev->inode) to release the reference.

[Severity: High]
This isn't a bug introduced by this patch, but is there a potential lockless
double-fetch of dax_dev->holder_ops in dax_holder_notify_failure() that could
lead to a NULL pointer dereference?

drivers/dax/super.c:dax_holder_notify_failure() {
    ...
	if (!dax_dev->holder_ops) {
		rc = -EOPNOTSUPP;
		goto out;
	}

	rc = dax_dev->holder_ops->notify_failure(dax_dev, off, len, mf_flags);
    ...
}

Since dax_dev->holder_ops is checked for NULL and then immediately
dereferenced without READ_ONCE(), the compiler might load the value twice.
If a concurrent fs_put_dax() executes WRITE_ONCE(dax_dev->holder_ops, NULL)
between these two loads, the second load could fetch NULL and cause a crash.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/0100019e79caead2-5795328c-af48-4a93-b147-c11df7446e1a-000000@email.amazonses.com?part=7

  reply	other threads:[~2026-05-30 18:08 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260530164953.6578-1-john@jagalactic.com>
2026-05-30 16:50 ` [PATCH V3 0/9] Fixes to the previously-merged drivers/dax/fsdev series John Groves
2026-05-30 16:50   ` [PATCH V3 1/9] dax: fix misleading comment about share/index union in dax_folio_reset_order() John Groves
2026-06-01 21:51     ` Dave Jiang
2026-06-03  0:12     ` Alison Schofield
2026-05-30 16:50   ` [PATCH V3 2/9] dax/fsdev: fix multi-range offset in memory_failure handler John Groves
2026-05-30 17:13     ` sashiko-bot
2026-06-03  0:12     ` Alison Schofield
2026-06-03  0:17     ` Dave Jiang
2026-05-30 16:50   ` [PATCH V3 3/9] dax/fsdev: clear vmemmap_shift when binding static pgmap John Groves
2026-05-30 17:28     ` sashiko-bot
2026-06-01 22:06     ` Dave Jiang
2026-06-03  0:13     ` Alison Schofield
2026-05-30 16:50   ` [PATCH V3 4/9] dax/fsdev: clear dev_dax->pgmap on probe failure John Groves
2026-05-30 17:37     ` sashiko-bot
2026-06-01 23:10     ` Dave Jiang
2026-06-03  0:14     ` Alison Schofield
2026-05-30 16:51   ` [PATCH V3 5/9] dax/fsdev: use __va(phys) for kaddr in direct_access John Groves
2026-05-30 17:48     ` sashiko-bot
2026-06-01 23:24     ` Dave Jiang
2026-06-03  0:14     ` Alison Schofield
2026-05-30 16:51   ` [PATCH V3 6/9] dax/fsdev: fail probe on invalid pgmap offset John Groves
2026-05-30 17:57     ` sashiko-bot
2026-06-03  0:15     ` Alison Schofield
2026-05-30 16:51   ` [PATCH V3 7/9] dax: fix holder_ops race in fs_put_dax() John Groves
2026-05-30 18:08     ` sashiko-bot [this message]
2026-06-02  0:03     ` Dave Jiang
2026-05-30 16:51   ` [PATCH V3 8/9] dax: replace exported dax_dev_get() with non-allocating dax_dev_find() John Groves
2026-05-30 18:20     ` sashiko-bot
2026-06-02  0:13     ` Dave Jiang
2026-06-03  0:15     ` Alison Schofield
2026-05-30 16:51   ` [PATCH V3 9/9] dax: fsdev.c minor formatting cleanup John Groves
2026-06-03  0:16     ` Alison Schofield
2026-06-03  0:11   ` [PATCH V3 0/9] Fixes to the previously-merged drivers/dax/fsdev series Alison Schofield

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=20260530180859.420861F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=john@jagalactic.com \
    --cc=linux-cxl@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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 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.