Currently, a file descriptor registered for preservation via the remains globally registered with LUO until it is explicitly unregistered. This creates a potential for resource leaks into the next kernel if the userspace agent crashes or exits without proper cleanup before a live update is fully initiated. This patch ties the lifetime of FD preservation requests to the lifetime of the open file descriptor for /dev/liveupdate, creating an implicit "session". When the /dev/liveupdate file descriptor is closed (either explicitly via close() or implicitly on process exit/crash), the .release handler, luo_release(), is now called. This handler invokes the new function luo_unregister_all_files(), which iterates through all FDs that were preserved through that session and unregisters them. Signed-off-by: Pasha Tatashin --- kernel/liveupdate/luo_files.c | 19 +++++++++++++++++++ kernel/liveupdate/luo_internal.h | 1 + kernel/liveupdate/luo_ioctl.c | 1 + 3 files changed, 21 insertions(+) diff --git a/kernel/liveupdate/luo_files.c b/kernel/liveupdate/luo_files.c index 33577c9e9a64..63f8b086b785 100644 --- a/kernel/liveupdate/luo_files.c +++ b/kernel/liveupdate/luo_files.c @@ -721,6 +721,25 @@ int luo_unregister_file(u64 token) return ret; } +/** + * luo_unregister_all_files - Unpreserve all currently registered files. + * + * Iterates through all file descriptors currently registered for preservation + * and unregisters them, freeing all associated resources. This is typically + * called when LUO agent exits. + */ +void luo_unregister_all_files(void) +{ + struct luo_file *luo_file; + unsigned long token; + + luo_state_read_enter(); + xa_for_each(&luo_files_xa_out, token, luo_file) + __luo_unregister_file(token); + luo_state_read_exit(); + WARN_ON_ONCE(atomic64_read(&luo_files_count) != 0); +} + /** * luo_retrieve_file - Find a registered file instance by its token. * @token: The unique token of the file instance to retrieve. diff --git a/kernel/liveupdate/luo_internal.h b/kernel/liveupdate/luo_internal.h index 5692196fd425..189e032d7738 100644 --- a/kernel/liveupdate/luo_internal.h +++ b/kernel/liveupdate/luo_internal.h @@ -37,5 +37,6 @@ void luo_do_subsystems_cancel_calls(void); int luo_retrieve_file(u64 token, struct file **filep); int luo_register_file(u64 token, int fd); int luo_unregister_file(u64 token); +void luo_unregister_all_files(void); #endif /* _LINUX_LUO_INTERNAL_H */ diff --git a/kernel/liveupdate/luo_ioctl.c b/kernel/liveupdate/luo_ioctl.c index 6f61569c94e8..7ca33d1c868f 100644 --- a/kernel/liveupdate/luo_ioctl.c +++ b/kernel/liveupdate/luo_ioctl.c @@ -137,6 +137,7 @@ static int luo_open(struct inode *inodep, struct file *filep) static int luo_release(struct inode *inodep, struct file *filep) { + luo_unregister_all_files(); atomic_set(&luo_device_in_use, 0); return 0; -- 2.50.1.565.gc32cd1483b-goog