[PATCH v2 3/8] liveupdate: Remove file handler module refcounting

Pasha Tatashin posted 8 patches 2 weeks, 5 days ago
There is a newer version of this series
[PATCH v2 3/8] liveupdate: Remove file handler module refcounting
Posted by Pasha Tatashin 2 weeks, 5 days ago
File handlers do not need to pin modules indefinitely or during active
live update sessions. The VFS 'struct file' pins the file handler's module
via f_op->owner during active sessions, making dynamic reference counting
unnecessary for handlers.

When a file is preserved, the live update core obtains a 'struct file'
via fdget(). As long as the file is kept open within the live update
session, the module is pinned by the VFS and cannot be unloaded.

Similarly, during deserialization, file handlers are matched based on
the compatible string. Because the handler list is protected by
luo_file_handler_lock, there is no race that requires dynamic
module refcounting.

Removing these module references ensures that modules implementing file
handlers can be unloaded when no longer providing active files.

Suggested-by: David Matlack <dmatlack@google.com>
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
---
 kernel/liveupdate/luo_file.c | 28 +++++++---------------------
 1 file changed, 7 insertions(+), 21 deletions(-)

diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c
index 96fdd5790dcc..b124fd747841 100644
--- a/kernel/liveupdate/luo_file.c
+++ b/kernel/liveupdate/luo_file.c
@@ -836,7 +836,6 @@ void luo_file_set_destroy(struct luo_file_set *file_set)
 int liveupdate_register_file_handler(struct liveupdate_file_handler *fh)
 {
 	struct liveupdate_file_handler *fh_iter;
-	int err;
 
 	if (!liveupdate_enabled())
 		return -EOPNOTSUPP;
@@ -861,17 +860,11 @@ int liveupdate_register_file_handler(struct liveupdate_file_handler *fh)
 			if (!strcmp(fh_iter->compatible, fh->compatible)) {
 				pr_err("File handler registration failed: Compatible string '%s' already registered.\n",
 				       fh->compatible);
-				err = -EEXIST;
-				goto err_resume;
+				luo_session_resume();
+				return -EEXIST;
 			}
 		}
 
-		/* Pin the module implementing the handler */
-		if (!try_module_get(fh->ops->owner)) {
-			err = -EAGAIN;
-			goto err_resume;
-		}
-
 		INIT_LIST_HEAD(&ACCESS_PRIVATE(fh, flb_list));
 		init_rwsem(&ACCESS_PRIVATE(fh, flb_lock));
 		INIT_LIST_HEAD(&ACCESS_PRIVATE(fh, list));
@@ -882,10 +875,6 @@ int liveupdate_register_file_handler(struct liveupdate_file_handler *fh)
 	liveupdate_test_register(fh);
 
 	return 0;
-
-err_resume:
-	luo_session_resume();
-	return err;
 }
 
 /**
@@ -907,8 +896,6 @@ int liveupdate_register_file_handler(struct liveupdate_file_handler *fh)
  */
 int liveupdate_unregister_file_handler(struct liveupdate_file_handler *fh)
 {
-	int err = -EBUSY;
-
 	if (!liveupdate_enabled())
 		return -EOPNOTSUPP;
 
@@ -918,19 +905,18 @@ int liveupdate_unregister_file_handler(struct liveupdate_file_handler *fh)
 		goto err_register;
 
 	scoped_guard(rwsem_write, &luo_file_handler_lock) {
-		if (!list_empty(&ACCESS_PRIVATE(fh, flb_list)))
-			goto err_resume;
+		if (!list_empty(&ACCESS_PRIVATE(fh, flb_list))) {
+			luo_session_resume();
+			goto err_register;
+		}
 
 		list_del(&ACCESS_PRIVATE(fh, list));
 	}
-	module_put(fh->ops->owner);
 	luo_session_resume();
 
 	return 0;
 
-err_resume:
-	luo_session_resume();
 err_register:
 	liveupdate_test_register(fh);
-	return err;
+	return -EBUSY;
 }
-- 
2.53.0.851.ga537e3e6e9-goog
Re: [PATCH v2 3/8] liveupdate: Remove file handler module refcounting
Posted by David Matlack 1 week, 5 days ago
On Wed, Mar 18, 2026 at 7:17 AM Pasha Tatashin
<pasha.tatashin@soleen.com> wrote:
>
> File handlers do not need to pin modules indefinitely or during active
> live update sessions. The VFS 'struct file' pins the file handler's module
> via f_op->owner during active sessions, making dynamic reference counting
> unnecessary for handlers.
>
> When a file is preserved, the live update core obtains a 'struct file'
> via fdget(). As long as the file is kept open within the live update
> session, the module is pinned by the VFS and cannot be unloaded.

After invoking the file handler's retrieve(), LUO should probably
check that the created file's owner matches the file handler's owner,
since this scheme relies on that being true.

If there is a mismatch, LUO can put the file that was just created,
log a warning, and return an error up to the user.
Re: [PATCH v2 3/8] liveupdate: Remove file handler module refcounting
Posted by Pasha Tatashin 1 week, 5 days ago
On Tue, Mar 24, 2026 at 5:24 PM David Matlack <dmatlack@google.com> wrote:
>
> On Wed, Mar 18, 2026 at 7:17 AM Pasha Tatashin
> <pasha.tatashin@soleen.com> wrote:
> >
> > File handlers do not need to pin modules indefinitely or during active
> > live update sessions. The VFS 'struct file' pins the file handler's module
> > via f_op->owner during active sessions, making dynamic reference counting
> > unnecessary for handlers.
> >
> > When a file is preserved, the live update core obtains a 'struct file'
> > via fdget(). As long as the file is kept open within the live update
> > session, the module is pinned by the VFS and cannot be unloaded.
>
> After invoking the file handler's retrieve(), LUO should probably
> check that the created file's owner matches the file handler's owner,
> since this scheme relies on that being true.
>
> If there is a mismatch, LUO can put the file that was just created,
> log a warning, and return an error up to the user.

Is there a reason why taking a file handler module reference is
problematic for vfio or iommu? Could we take it while files are
present in incoming or outgoing sessions? Overall, it is because it
cover corener cases such as if the file struct owner is the same as
LUO file handler and also this approach covers the deserialziation
side nicely.

Pasha
Re: [PATCH v2 3/8] liveupdate: Remove file handler module refcounting
Posted by David Matlack 1 week, 5 days ago
On Tue, Mar 24, 2026 at 7:49 PM Pasha Tatashin
<pasha.tatashin@soleen.com> wrote:
>
> On Tue, Mar 24, 2026 at 5:24 PM David Matlack <dmatlack@google.com> wrote:
> >
> > On Wed, Mar 18, 2026 at 7:17 AM Pasha Tatashin
> > <pasha.tatashin@soleen.com> wrote:
> > >
> > > File handlers do not need to pin modules indefinitely or during active
> > > live update sessions. The VFS 'struct file' pins the file handler's module
> > > via f_op->owner during active sessions, making dynamic reference counting
> > > unnecessary for handlers.
> > >
> > > When a file is preserved, the live update core obtains a 'struct file'
> > > via fdget(). As long as the file is kept open within the live update
> > > session, the module is pinned by the VFS and cannot be unloaded.
> >
> > After invoking the file handler's retrieve(), LUO should probably
> > check that the created file's owner matches the file handler's owner,
> > since this scheme relies on that being true.
> >
> > If there is a mismatch, LUO can put the file that was just created,
> > log a warning, and return an error up to the user.
>
> Is there a reason why taking a file handler module reference is
> problematic for vfio or iommu? Could we take it while files are
> present in incoming or outgoing sessions? Overall, it is because it
> cover corener cases such as if the file struct owner is the same as
> LUO file handler and also this approach covers the deserialziation
> side nicely.

I see no problem with LUO taking a reference to the file handle module
owner while a file associated with it is preserved in an incoming or
outgoing session.

And I realized that VFIO can have different owners for the file (vfio
module) and file handler (vfio-pci module), as it is currently
implemented. It should still be safe to rely on the file reference,
but explicitly taking a reference to the file handler would be simpler
to reason about. So I am ok with going back to what you had in v1 [1].

[1] https://lore.kernel.org/lkml/20260317025049.494931-4-pasha.tatashin@soleen.com/
Re: [PATCH v2 3/8] liveupdate: Remove file handler module refcounting
Posted by Pasha Tatashin 1 week, 5 days ago
On Wed, Mar 25, 2026 at 9:15 AM David Matlack <dmatlack@google.com> wrote:
>
> On Tue, Mar 24, 2026 at 7:49 PM Pasha Tatashin
> <pasha.tatashin@soleen.com> wrote:
> >
> > On Tue, Mar 24, 2026 at 5:24 PM David Matlack <dmatlack@google.com> wrote:
> > >
> > > On Wed, Mar 18, 2026 at 7:17 AM Pasha Tatashin
> > > <pasha.tatashin@soleen.com> wrote:
> > > >
> > > > File handlers do not need to pin modules indefinitely or during active
> > > > live update sessions. The VFS 'struct file' pins the file handler's module
> > > > via f_op->owner during active sessions, making dynamic reference counting
> > > > unnecessary for handlers.
> > > >
> > > > When a file is preserved, the live update core obtains a 'struct file'
> > > > via fdget(). As long as the file is kept open within the live update
> > > > session, the module is pinned by the VFS and cannot be unloaded.
> > >
> > > After invoking the file handler's retrieve(), LUO should probably
> > > check that the created file's owner matches the file handler's owner,
> > > since this scheme relies on that being true.
> > >
> > > If there is a mismatch, LUO can put the file that was just created,
> > > log a warning, and return an error up to the user.
> >
> > Is there a reason why taking a file handler module reference is
> > problematic for vfio or iommu? Could we take it while files are
> > present in incoming or outgoing sessions? Overall, it is because it
> > cover corener cases such as if the file struct owner is the same as
> > LUO file handler and also this approach covers the deserialziation
> > side nicely.
>
> I see no problem with LUO taking a reference to the file handle module
> owner while a file associated with it is preserved in an incoming or
> outgoing session.
>
> And I realized that VFIO can have different owners for the file (vfio
> module) and file handler (vfio-pci module), as it is currently
> implemented. It should still be safe to rely on the file reference,
> but explicitly taking a reference to the file handler would be simpler
> to reason about. So I am ok with going back to what you had in v1 [1].

Great, I will include this in v3, together with Sami's suggestion for
lock simplifications.

Pasha

>
> [1] https://lore.kernel.org/lkml/20260317025049.494931-4-pasha.tatashin@soleen.com/
Re: [PATCH v2 3/8] liveupdate: Remove file handler module refcounting
Posted by David Matlack 1 week, 5 days ago
On 2026-03-18 10:16 AM, Pasha Tatashin wrote:
> File handlers do not need to pin modules indefinitely or during active
> live update sessions. The VFS 'struct file' pins the file handler's module
> via f_op->owner during active sessions, making dynamic reference counting
> unnecessary for handlers.
> 
> When a file is preserved, the live update core obtains a 'struct file'
> via fdget(). As long as the file is kept open within the live update
> session, the module is pinned by the VFS and cannot be unloaded.
> 
> Similarly, during deserialization, file handlers are matched based on
> the compatible string. Because the handler list is protected by
> luo_file_handler_lock, there is no race that requires dynamic
> module refcounting.

Sashiko found a potential bug here when reviewing my VFIO patch series:

. If luo_file_deserialize() reconstructs preserved file structures and
. assigns the handler to luo_file->fh without calling try_module_get()
. to lock the module in memory, could the module be unloaded before the
. file descriptor is actually retrieved?
.
. This would cause liveupdate_unregister_file_handler() to run on module exit.
. If userspace subsequently calls luo_retrieve_file(), could it result
. in a use-after-free by dereferencing the dangling luo_file->fh->ops pointer?

https://sashiko.dev/#/patchset/20260323235817.1960573-1-dmatlack%40google.com?patch=7973

I think LUO would need to take a module reference in
luo_file_deserialize() and drop it once the file is retrieved. At that
point LUO can rely on the file's reference to the module to keep it from
being unloaded while LUO still has references to it.