linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH,RFC] livepatch: fix race between fork and klp_reverse_transition
@ 2022-07-20 16:10 Rik van Riel
  2022-07-21 23:23 ` Song Liu
  2022-07-22 15:30 ` Petr Mladek
  0 siblings, 2 replies; 13+ messages in thread
From: Rik van Riel @ 2022-07-20 16:10 UTC (permalink / raw)
  To: linux-kernel
  Cc: live-patching, kernel-team, Josh Poimboeuf, Jiri Kosina,
	Miroslav Benes, Petr Mladek, Joe Lawrence, Breno Leitao

When a KLP fails to apply, klp_reverse_transition will clear the
TIF_PATCH_PENDING flag on all tasks, except for newly created tasks
which are not on the task list yet.

Meanwhile, fork will copy over the TIF_PATCH_PENDING flag from the
parent to the child early on, in dup_task_struct -> setup_thread_stack.

Much later, klp_copy_process will set child->patch_state to match
that of the parent.

However, the parent's patch_state may have been changed by KLP loading
or unloading since it was initially copied over into the child.

This results in the KLP code occasionally hitting this warning in
klp_complete_transition:

        for_each_process_thread(g, task) {
                WARN_ON_ONCE(test_tsk_thread_flag(task, TIF_PATCH_PENDING));
                task->patch_state = KLP_UNDEFINED;
        }

This patch will set, or clear, the TIF_PATCH_PENDING flag in the child
process depending on whether or not it is needed at the time
klp_copy_process is called, at a point in copy_process where the
tasklist_lock is held exclusively, preventing races with the KLP
code.

This should prevent this warning from triggering again in the
future.

I have not yet figured out whether this would also help with races in
the other direction, where the child process fails to have TIF_PATCH_PENDING
set and somehow misses a transition, or whether the retries in
klp_try_complete_transition would catch that task and help it transition
later.

Signed-off-by: Rik van Riel <riel@surriel.com>
Reported-by: Breno Leitao <leitao@debian.org>
---
 kernel/livepatch/transition.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index 5d03a2ad1066..7a90ad5e9224 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -612,7 +612,15 @@ void klp_copy_process(struct task_struct *child)
 {
 	child->patch_state = current->patch_state;
 
-	/* TIF_PATCH_PENDING gets copied in setup_thread_stack() */
+	/*
+	 * The parent process may have gone through a KLP transition since
+	 * the thread flag was copied in setup_thread_stack earlier. Set
+	 * the flag according to whether this task needs a KLP transition.
+	 */
+	if (child->patch_state != klp_target_state)
+		set_tsk_thread_flag(child, TIF_PATCH_PENDING);
+	else
+		clear_tsk_thread_flag(child, TIF_PATCH_PENDING);
 }
 
 /*
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2022-08-04 13:06 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-20 16:10 [PATCH,RFC] livepatch: fix race between fork and klp_reverse_transition Rik van Riel
2022-07-21 23:23 ` Song Liu
2022-07-22 15:30 ` Petr Mladek
2022-07-22 19:01   ` [PATCH v2] " Rik van Riel
2022-07-25 13:32     ` Petr Mladek
2022-07-25 13:49       ` [PATCH v3] " Rik van Riel
2022-07-27  0:10         ` Josh Poimboeuf
2022-07-27  0:26           ` Rik van Riel
2022-07-28 15:20             ` Petr Mladek
2022-07-27 14:24           ` [PATCH v4] livepatch: fix race between fork and KLP transition Rik van Riel
2022-07-28 15:37             ` Petr Mladek
2022-08-02 20:07               ` Rik van Riel
2022-08-04 13:06                 ` Petr Mladek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).