]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
liveupdate: fix u-a-f in luo_file_unpreserve_files() and luo_file_finish()
authorPasha Tatashin <pasha.tatashin@soleen.com>
Wed, 27 May 2026 20:27:36 +0000 (20:27 +0000)
committerMike Rapoport (Microsoft) <rppt@kernel.org>
Mon, 1 Jun 2026 06:19:38 +0000 (09:19 +0300)
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@kernel.org>
Reviewed-by: Pratyush Yadav (Google) <pratyush@kernel.org>
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Link: https://patch.msgid.link/20260527202737.1345192-5-pasha.tatashin@soleen.com
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
kernel/liveupdate/luo_file.c

index a0a419085e2830a20d37f920a8d157d6453d3823..208987502f73a9d7b84107330db910e15be8594e 100644 (file)
@@ -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);