[PATCH 5/5] liveupdate: guard FLB counters against underflow
From: Oskar Gerlicz Kowalczuk
Date: Fri Mar 20 2026 - 13:43:48 EST
The FLB lifetime counters are decremented unconditionally on
unpreserve and finish. If either path runs with a zero counter, the
value wraps and the FLB state appears to stay live forever.
Once the counter underflows, later handover operations can act on
stale FLB state or skip the real final teardown, which makes restore
and finish lifetime tracking unreliable.
Guard both counters against zero and warn once instead of
decrementing. This keeps the existing lifetime rules intact while
preventing wraparound.
Signed-off-by: Oskar Gerlicz Kowalczuk <oskar@gerlicz.space>
---
kernel/liveupdate/luo_flb.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c
index 3672cbf8e075..06501360fa3f 100644
--- a/kernel/liveupdate/luo_flb.c
+++ b/kernel/liveupdate/luo_flb.c
@@ -128,6 +128,9 @@ static void luo_flb_file_unpreserve_one(struct liveupdate_flb *flb)
struct luo_flb_private *private = luo_flb_get_private(flb);
scoped_guard(mutex, &private->outgoing.lock) {
+ if (WARN_ON_ONCE(!private->outgoing.count))
+ return;
+
private->outgoing.count--;
if (!private->outgoing.count) {
struct liveupdate_flb_op_args args = {0};
@@ -201,8 +204,12 @@ static void luo_flb_file_finish_one(struct liveupdate_flb *flb)
struct luo_flb_private *private = luo_flb_get_private(flb);
u64 count;
- scoped_guard(mutex, &private->incoming.lock)
+ scoped_guard(mutex, &private->incoming.lock) {
+ if (WARN_ON_ONCE(!private->incoming.count))
+ return;
+
count = --private->incoming.count;
+ }
if (!count) {
struct liveupdate_flb_op_args args = {0};
--
2.53.0