Prevent an incoming FLB from being retrieved after its finish() callback has been run. An incoming FLB should only retrieved once, and once its finish() callback has run the data has been freed and cannot be (and should not be) retrieved again.
Fixes: e8c57e582167 ("liveupdate: luo_flb: Introduce File-Lifecycle-Bound global state") Signed-off-by: David Matlack dmatlack@google.com --- include/linux/liveupdate.h | 3 +++ kernel/liveupdate/luo_flb.c | 4 ++++ 2 files changed, 7 insertions(+)
diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h index ed81e7b31a9f..b913d63eab5f 100644 --- a/include/linux/liveupdate.h +++ b/include/linux/liveupdate.h @@ -165,12 +165,15 @@ struct liveupdate_flb_ops { * @obj: The live kernel object returned by .preserve() or .retrieve(). * @lock: A mutex that protects all fields within this structure, providing * the synchronization service for the FLB's ops. + * @finished: True once the FLB's finish() callback has run, to prevent an FLB + * from being retrieve()'d again after finish() (incoming only). */ struct luo_flb_private_state { long count; u64 data; void *obj; struct mutex lock; + bool finished; };
/* diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c index e80ac5b575ec..072796fb75cb 100644 --- a/kernel/liveupdate/luo_flb.c +++ b/kernel/liveupdate/luo_flb.c @@ -155,6 +155,9 @@ static int luo_flb_retrieve_one(struct liveupdate_flb *flb)
guard(mutex)(&private->incoming.lock);
+ if (private->incoming.finished) + return -ENODATA; + if (private->incoming.obj) return 0;
@@ -213,6 +216,7 @@ static void luo_flb_file_finish_one(struct liveupdate_flb *flb)
private->incoming.data = 0; private->incoming.obj = NULL; + private->incoming.finished = true; } } }