[PATCH v6 4/5] liveupdate: fix u-a-f in luo_file_unpreserve_files() and luo_file_finish()

From: Pasha Tatashin

Date: Wed May 27 2026 - 16:28:51 EST


In luo_file_unpreserve_files() and luo_file_finish(), reorder
module_put() and xa_erase() to ensure the file handler module remains
pinned while its operations are being accessed.

Specifically, luo_get_id() dereferences fh->ops->get_id, so the module
reference must be held until after xa_erase() (which calls luo_get_id)
completes.

For luo_file_finish(), this requires moving the module_put() call out of
the luo_file_finish_one() helper and into the main loop of
luo_file_finish() itself.

Fixes: 00d0b372374f ("liveupdate: prevent double management of files")
Acked-by: Mike Rapoport (Microsoft) <rppt@xxxxxxxxxx>
Reviewed-by: Pratyush Yadav (Google) <pratyush@xxxxxxxxxx>
Signed-off-by: Pasha Tatashin <pasha.tatashin@xxxxxxxxxx>
---
kernel/liveupdate/luo_file.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c
index a0a419085e28..208987502f73 100644
--- a/kernel/liveupdate/luo_file.c
+++ b/kernel/liveupdate/luo_file.c
@@ -385,10 +385,11 @@ void luo_file_unpreserve_files(struct luo_file_set *file_set)
args.private_data = luo_file->private_data;
luo_file->fh->ops->unpreserve(&args);
luo_flb_file_unpreserve(luo_file->fh);
- module_put(luo_file->fh->ops->owner);

xa_erase(&luo_preserved_files,
luo_get_id(luo_file->fh, luo_file->file));
+ module_put(luo_file->fh->ops->owner);
+
list_del(&luo_file->list);
file_set->count--;

@@ -677,7 +678,6 @@ static void luo_file_finish_one(struct luo_file_set *file_set,

luo_file->fh->ops->finish(&args);
luo_flb_file_finish(luo_file->fh);
- module_put(luo_file->fh->ops->owner);
}

/**
@@ -738,6 +738,7 @@ int luo_file_finish(struct luo_file_set *file_set)
luo_get_id(luo_file->fh, luo_file->file));
fput(luo_file->file);
}
+ module_put(luo_file->fh->ops->owner);
list_del(&luo_file->list);
file_set->count--;
mutex_destroy(&luo_file->mutex);
--
2.53.0