Received: by 2002:ac0:e34a:0:0:0:0:0 with SMTP id g10csp354660imn; Wed, 27 Jul 2022 08:05:37 -0700 (PDT) X-Google-Smtp-Source: AGRyM1uCrCeRWGlBvRwYKocRCKrChQJO61RPHOT8lBNQjYNlN0L+yu3x9mdNLedvJD4AwdRuab0L X-Received: by 2002:a17:90b:38c5:b0:1ef:a7ad:ebb9 with SMTP id nn5-20020a17090b38c500b001efa7adebb9mr5282670pjb.110.1658934336784; Wed, 27 Jul 2022 08:05:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658934336; cv=none; d=google.com; s=arc-20160816; b=zWG/lh7qmGehnE2GwG6WNiQfzy1N8rUW/oGZ8YFct6uG41pBVnYtWOm6B2lqPNNlBW N/9BI3AjV+oYpyKNVyltLKxwMH+8xSi3dloMl5KmV5rhA4BRSo/27kwUlTXObQ3/+lsI lVXRIV7b8uOgT16iyh0GPm2IMvRJD53+4Vd+TkrmtpAQr9DCB0uoLcGIxpuhhn3U246Z gkhQzNvHM/8I+sZXDfJmRr0tIHgNOtrOQTQ3pEzJOhtm5L2kEZpF7pweLIc26kg8AED2 0ZrQmxrZKEDruem0CMhifpbyiY3fikXb+P5KwemSC/Nc5nrkP3PAK3MZF3TFJEr5Idxm SLkQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:subject:cc:to:from:date; bh=s4LkeGxAuEraCSkPkgJ0GOkUO4joSJHcWw4ukZICyKc=; b=JoS3v0safWRREIAuiEDWDpBxYHPr3tU6KwRk93qkZ2S55EYv4nKUL7teqgm7xO2Xas iCnF1utSRc0LID6/SwGmu+TJntjJNqjX05hARMs2y9QToF/ZfYaHTWhyX2CboW63eJuK lJrL3nkC1Ek16i07Tj7T8nAJExZiUlHbUetNPIXj6Neu7qCcfmmcrNTuIn7LXtP71Fm2 bvSgUJlKb5skvON1zy17NTAgg1N38/hL177JnUm9Fnp9hC84gbU7pqbzPVPcvXLZtGC2 bc8HpW+HNxfzgNPi5dml/cTLGXNIGrDxO+T7zzzGmU2PuxnOSTJZLryFrzbmmRX8eBRT U12Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b36-20020a630c24000000b0041a6822684bsi20493760pgl.213.2022.07.27.08.05.20; Wed, 27 Jul 2022 08:05:36 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233708AbiG0OYs (ORCPT + 99 others); Wed, 27 Jul 2022 10:24:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49956 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233565AbiG0OYq (ORCPT ); Wed, 27 Jul 2022 10:24:46 -0400 Received: from shelob.surriel.com (shelob.surriel.com [96.67.55.147]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F24E624BC8; Wed, 27 Jul 2022 07:24:45 -0700 (PDT) Received: from [2603:3005:d05:2b00:6e0b:84ff:fee2:98bb] (helo=imladris.surriel.com) by shelob.surriel.com with esmtpsa (TLS1.2) tls TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1oGhxl-0008Bo-Ua; Wed, 27 Jul 2022 10:24:37 -0400 Date: Wed, 27 Jul 2022 10:24:37 -0400 From: Rik van Riel To: Josh Poimboeuf Cc: Petr Mladek , linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, kernel-team@fb.com, Jiri Kosina , Miroslav Benes , Joe Lawrence , Breno Leitao Subject: [PATCH v4] livepatch: fix race between fork and KLP transition Message-ID: <20220727102437.34530586@imladris.surriel.com> In-Reply-To: <20220727001040.vlqnnb4a3um46746@treble> References: <20220720121023.043738bb@imladris.surriel.com> <20220722150106.683f3704@imladris.surriel.com> <20220725094919.52bcde19@imladris.surriel.com> <20220727001040.vlqnnb4a3um46746@treble> X-Mailer: Claws Mail 4.0.0 (GTK+ 3.24.31; x86_64-redhat-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: riel@shelob.surriel.com X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org v4: address changelog comments by Josh (thank you) ---8<--- 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. A similar race is possible for normal (forward) transitions, where TIF_PATCH_PENDING gets copied to the child, then later cleared in the parent. 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; } Set, or clear, the TIF_PATCH_PENDING flag in the child task 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. The KLP code does have a few places where the state is changed without the tasklist_lock held, but those should not cause problems because klp_update_patch_state(current) cannot be called while the current task is in the middle of fork, klp_check_and_switch_task() which is called under the pi_lock, which prevents rescheduling, and manipulation of the patch state of idle tasks, which do not fork. This should prevent this warning from triggering again in the future, and close the race for both normal and reverse transitions. Signed-off-by: Rik van Riel Reported-by: Breno Leitao Reviewed-by: Petr Mladek Acked-by: Josh Poimboeuf Fixes: d83a7cb375ee ("livepatch: change to a per-task consistency model") Cc: stable@kernel.org --- kernel/livepatch/transition.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c index 5d03a2ad1066..30187b1d8275 100644 --- a/kernel/livepatch/transition.c +++ b/kernel/livepatch/transition.c @@ -610,9 +610,23 @@ void klp_reverse_transition(void) /* Called from copy_process() during fork */ 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. Bring + * the task flag up to date with the parent here. + * + * The operation is serialized against all klp_*_transition() + * operations by the tasklist_lock. The only exception is + * klp_update_patch_state(current), but we cannot race with + * that because we are current. + */ + if (test_tsk_thread_flag(current, TIF_PATCH_PENDING)) + set_tsk_thread_flag(child, TIF_PATCH_PENDING); + else + clear_tsk_thread_flag(child, TIF_PATCH_PENDING); + + child->patch_state = current->patch_state; } /* -- 2.35.1