Re: [PATCH V12 01/12] dax: replace exported dax_dev_get() with non-allocating dax_dev_find()

[email protected] Mon, 03 Aug 2026 02:43:14 +0000
Newsgroups dev.linux.lists.nvdimm,org.kernel.vger.linux-cxl
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 1 potential issue(=
s) to consider:

Pre-existing issues:
- [High] Race Condition / Uninitialized Data Access during DAX device alloc=
ation.
--

--- Patch [1]: [PATCH V12 01/12] dax: replace exported dax_dev_get() with n=
on-allocating dax_dev_find() ---
commit ff957b44b15e4c0e4aaedcf9cd2d12118ab1bb27
Author: John Groves <[email protected]>

dax: replace exported dax_dev_get() with non-allocating dax_dev_find()

This patch introduces dax_dev_find() to look up existing DAX devices
without allocating a new inode, preventing empty inodes from being created
when external callers provide user-supplied device numbers. It also makes
dax_dev_get() static and updates external references.

> diff --git a/drivers/dax/super.c b/drivers/dax/super.c
> index 25cf99dd9360b..0fc14d4f81989 100644
> --- a/drivers/dax/super.c
> +++ b/drivers/dax/super.c
[ ... ]
> @@ -544,7 +544,41 @@ struct dax_device *dax_dev_get(dev_t devt)
> =20
>  	return dax_dev;
>  }
> -EXPORT_SYMBOL_GPL(dax_dev_get);
> +
> +/**
> + * dax_dev_find - look up an existing dax_device by dev_t
[ ... ]
> + */
> +struct dax_device *dax_dev_find(dev_t devt)
> +{
> +	struct dax_device *dax_dev;
> +	struct inode *inode;
> +	int id;
> +
> +	inode =3D ilookup5(dax_superblock, hash_32(devt + DAXFS_MAGIC, 31),
> +			 dax_test, &devt);
> +	if (!inode)
> +		return NULL;
> +
> +	dax_dev =3D to_dax_dev(inode);
> +	id =3D dax_read_lock();
> +	if (!dax_alive(dax_dev)) {
> +		dax_read_unlock(id);
> +		iput(inode);
> +		return NULL;
> +	}
> +	dax_read_unlock(id);
> +
> +	return dax_dev;
> +}

[Severity: High]
This isn't a bug introduced by this patch, but could a concurrent caller of
dax_dev_find() obtain a partially initialized device here?

In dax_dev_get(), unlock_new_inode() clears I_NEW and makes the DAX device
visible to ilookup5(). However, alloc_dax() sets the ops and private
pointers after dax_dev_get() returns:

alloc_dax() {
    ...
    dax_dev =3D dax_dev_get(devt);
    if (!dax_dev)
        goto err_dev;

    dax_dev->ops =3D ops;
    dax_dev->private =3D private;
    ...
}

Because dax_dev_find() retrieves the device from the inode cache and only
checks if DAXDEV_ALIVE is set, could an external caller using a guessed
device number observe NULL ops or private pointers?=20

If the external caller attempts to use the returned device before alloc_dax=
()
completes, could this lead to a NULL pointer dereference and kernel panic?

> +EXPORT_SYMBOL_GPL(dax_dev_find);

--=20
Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/0100019fc572ca94-ec=
[email protected]?part=3D1