[PATCH v2 3/3] liveupdate: block outgoing session mutations
Pasha Tatashin
pasha.tatashin at soleen.com
Wed May 6 11:20:43 PDT 2026
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 <oskar at gerlicz.space>
Signed-off-by: Pasha Tatashin <pasha.tatashin at soleen.com>
---
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
More information about the kexec
mailing list