During the reboot() syscall, user processes may still be running concurrently and attempting to mutate sessions (e.g., adding files or closing sessions). To prevent this, hold the session header's rwsem and each session's mutex indefinitely on successful serialization. If serialization succeeds, these locks will never be released as the system transitions to the new kernel, effectively blocking any concurrent task attempting to modify or release a session. If liveupdate_reboot() fails, the locks are released in the error path, allowing normal operation to resume. Fixes: 0153094d03df ("liveupdate: luo_session: add sessions support") Reported-by: Oskar Gerlicz Kowalczuk Signed-off-by: Pasha Tatashin --- kernel/liveupdate/luo_session.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_session.c index a3327a28fc1f..12808c696def 100644 --- a/kernel/liveupdate/luo_session.c +++ b/kernel/liveupdate/luo_session.c @@ -189,14 +189,14 @@ static int luo_session_finish_one(struct luo_session *session) static void luo_session_unfreeze_one(struct luo_session *session, struct luo_session_ser *ser) { - guard(mutex)(&session->mutex); + lockdep_assert_held(&session->mutex); luo_file_unfreeze(&session->file_set, &ser->file_set_ser); } static int luo_session_freeze_one(struct luo_session *session, struct luo_session_ser *ser) { - guard(mutex)(&session->mutex); + lockdep_assert_held(&session->mutex); return luo_file_freeze(&session->file_set, &ser->file_set_ser); } @@ -583,7 +583,10 @@ int luo_session_serialize(void) int i = 0; int err; - guard(rwsem_write)(&sh->rwsem); + down_write(&sh->rwsem); + list_for_each_entry(session, &sh->list, list) + mutex_lock_nest_lock(&session->mutex, &sh->rwsem); + list_for_each_entry(session, &sh->list, list) { err = luo_session_freeze_one(session, &sh->ser[i]); if (err) @@ -603,6 +606,9 @@ int luo_session_serialize(void) luo_session_unfreeze_one(session, &sh->ser[i]); memset(sh->ser[i].name, 0, sizeof(sh->ser[i].name)); } + list_for_each_entry(session, &sh->list, list) + mutex_unlock(&session->mutex); + up_write(&sh->rwsem); return err; } -- 2.54.0.545.g6539524ca2-goog