lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <68d45a76a36ad_1c79100a6@dwillia2-mobl4.notmuch>
Date: Wed, 24 Sep 2025 13:54:14 -0700
From: <dan.j.williams@...el.com>
To: Tzung-Bi Shih <tzungbi@...nel.org>, Benson Leung <bleung@...omium.org>,
	Greg Kroah-Hartman <gregkh@...uxfoundation.org>, "Rafael J . Wysocki"
	<rafael@...nel.org>, Danilo Krummrich <dakr@...nel.org>
CC: Jonathan Corbet <corbet@....net>, Shuah Khan <shuah@...nel.org>, "Dawid
 Niedzwiecki" <dawidn@...gle.com>, <linux-doc@...r.kernel.org>,
	<linux-kernel@...r.kernel.org>, <chrome-platform@...ts.linux.dev>,
	<linux-kselftest@...r.kernel.org>, <tzungbi@...nel.org>, Laurent Pinchart
	<laurent.pinchart@...asonboard.com>, Bartosz Golaszewski <brgl@...ev.pl>,
	Wolfram Sang <wsa+renesas@...g-engineering.com>
Subject: Re: [PATCH v4 5/7] revocable: Add fops replacement

Tzung-Bi Shih wrote:
> Introduce revocable_replace_fops() to simplify the use of the revocable
> API with file_operations.
> 
> The function, should be called from a driver's ->open(), replaces the
> fops with a wrapper that automatically handles the `try_access` and
> `withdraw_access`.
> 
> When the file is closed, the wrapper's ->release() restores the original
> fops and cleanups.  This centralizes the revocable logic, making drivers
> cleaner and easier to maintain.
> 
> Signed-off-by: Tzung-Bi Shih <tzungbi@...nel.org>
[..]
> +/**
> + * revocable_replace_fops() - Replace the file operations to be revocable-aware.
> + *
> + * Should be used only from ->open() instances.
> + */
> +int revocable_replace_fops(struct file *filp, struct revocable_provider *rp,
> +			   const struct revocable_operations *rops)
> +{
> +	struct fops_replacement *fr;
> +
> +	fr = kzalloc(sizeof(*fr), GFP_KERNEL);
> +	if (!fr)
> +		return -ENOMEM;
> +
> +	fr->filp = filp;
> +	fr->rops = rops;
> +	fr->orig_fops = filp->f_op;
> +	fr->rev = revocable_alloc(rp);
> +	if (!fr->rev)
> +		return -ENOMEM;
> +	memcpy(&fr->fops, filp->f_op, sizeof(struct file_operations));
> +	scoped_guard(mutex, &fops_replacement_mutex)
> +		list_add(&fr->list, &fops_replacement_list);

This list grows for every active instance? Unless I am misreading, that
looks like a scaling burden that the simple approach below does not
have.

> +	fr->fops.release = revocable_fr_release;
> +
> +	if (filp->f_op->read)
> +		fr->fops.read = revocable_fr_read;
> +	if (filp->f_op->poll)
> +		fr->fops.poll = revocable_fr_poll;
> +	if (filp->f_op->unlocked_ioctl)
> +		fr->fops.unlocked_ioctl = revocable_fr_unlocked_ioctl;
> +
> +	filp->f_op = &fr->fops;
> +	return 0;
> +}

This facility is protecting the wrong resource, and I argue hides bugs
in drivers that think they need this. That matches the conclusion I came
to with my "managed_fops" attempt.

The resource that is being revoked is the device's attachment to its
driver. Whether that is dev_get_drvdata() or some other device-to-data
lookup, that is the resource that gets removed, not the fops themselves.
The only resource race with fops is whether the code text section
remains available while the fops are registered, but that lifetime scope
is not at a per-device instance scope.

revocable() could be useful for more complicated scenarios, but for
making sure that ->unlocked_ioctl(), ->poll(), and ->read() start
reliably failing, just do:

    guard(rwsem_read)(&subsystem_device_registration_lock);
    data = subsystem_lookup_device_relative_data(...)
    if (data)
        return subsystem_{ioctl,poll,read}(data, ...);
    return -ENXIO;

...and revoke future subsystem_{ioctl,poll,read}() invocations by making
subsystem_lookup_device_relative_data() start failing under
guard(rwsem_write)(&subsystem_device_registration_lock).

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ