From patchwork Tue Feb 20 19:24:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuxuan Luo X-Patchwork-Id: 1901640 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TfTr321LVz1yP6 for ; Wed, 21 Feb 2024 06:24:51 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1rcVjL-0008Dz-Id; Tue, 20 Feb 2024 19:24:40 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1rcVjH-0008DW-6j for kernel-team@lists.ubuntu.com; Tue, 20 Feb 2024 19:24:35 +0000 Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id D0C073F68D for ; Tue, 20 Feb 2024 19:24:34 +0000 (UTC) Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-1dbde5c4d68so22065325ad.2 for ; Tue, 20 Feb 2024 11:24:34 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708457071; x=1709061871; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rKNftPFe7V6z3KoqWNG/l2P1QfuiJhY38DIu8Txa3mg=; b=dlYrD9VsOFbDlyxE/4j2ztZrn7cpclcF0/lGec6AFgJ9Rz3a9hseszhlg3dopfdFKQ MGUf6NXLSA8GDZPxBkLNXpZN9xKNLPzi26xFWzRqsMMvFJwfOVaDefltVlU3f22GPQHy UvzPFtI6jxPllzSHGVGwzIWr5CBuHj7GX4DkdABjayMdTYEK8mSHtwk1TBq/WDfLFxS2 YzL3DL/vr3irvC9znqCGQGFjbw5z4DFpKhuSHA1EOdDU46Bl8pUvRpgu/glTbkuiRywR BWDooXwJNXJnvd5oyZ44NSWvnoa4EzYyveoG+EJKCizmImNGUMw437AAqa0HJnP4EnAE 3Rrg== X-Gm-Message-State: AOJu0YzzvUl123MLwMJp6JAWhpc24LlD78I08APuoEmnh9LPK6N54Hrp YNmLB9LN/xteesTTitk5DF5LwGO8wyvCzIheGaAh8T2o6CcO5/HFCX2sfOVcvkp25Qzha0Fgc+5 i437VB22dqeoX3h8EX1wwto3l5yIru0XSDiDcYLzOoxIbglyHT1P1sw5Yj2y+uaEPwVyUJY7KTc 5qpYBDMK67kA== X-Received: by 2002:a17:902:eb84:b0:1dc:1ff2:c6d6 with SMTP id q4-20020a170902eb8400b001dc1ff2c6d6mr2081351plg.22.1708457071522; Tue, 20 Feb 2024 11:24:31 -0800 (PST) X-Google-Smtp-Source: AGHT+IE5au+cIQTey/Kxb0/Pv+L8c9lVsECOcKwp+8kYfYpZydmnXH+wQ96PHZb2xz4FIl+Fm6jriQ== X-Received: by 2002:a17:902:eb84:b0:1dc:1ff2:c6d6 with SMTP id q4-20020a170902eb8400b001dc1ff2c6d6mr2081336plg.22.1708457071199; Tue, 20 Feb 2024 11:24:31 -0800 (PST) Received: from cache-ubuntu.hsd1.nj.comcast.net ([2001:67c:1562:8007::aac:4795]) by smtp.gmail.com with ESMTPSA id l21-20020a170902e2d500b001d9fcd343edsm6639440plc.208.2024.02.20.11.24.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Feb 2024 11:24:30 -0800 (PST) From: Yuxuan Luo To: kernel-team@lists.ubuntu.com Subject: [SRU][OEM-6.1][PATCH 1/8] timers: Use del_timer_sync() even on UP Date: Tue, 20 Feb 2024 14:24:14 -0500 Message-Id: <20240220192421.35003-2-yuxuan.luo@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240220192421.35003-1-yuxuan.luo@canonical.com> References: <20240220192421.35003-1-yuxuan.luo@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Thomas Gleixner del_timer_sync() is assumed to be pointless on uniprocessor systems and can be mapped to del_timer() because in theory del_timer() can never be invoked while the timer callback function is executed. This is not entirely true because del_timer() can be invoked from interrupt context and therefore hit in the middle of a running timer callback. Contrary to that del_timer_sync() is not allowed to be invoked from interrupt context unless the affected timer is marked with TIMER_IRQSAFE. del_timer_sync() has proper checks in place to detect such a situation. Give up on the UP optimization and make del_timer_sync() unconditionally available. Co-developed-by: Steven Rostedt Signed-off-by: Steven Rostedt Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Jacob Keller Reviewed-by: Anna-Maria Behnsen Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org Link: https://lore.kernel.org/r/20221123201624.888306160@linutronix.de (cherry picked from commit 168f6b6ffbeec0b9333f3582e4cf637300858db5) CVE-2023-6039 Signed-off-by: Yuxuan Luo --- include/linux/timer.h | 7 +------ kernel/time/timer.c | 2 -- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/include/linux/timer.h b/include/linux/timer.h index 648f00105f58..82bb2e4d3b7c 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -183,12 +183,7 @@ extern int timer_reduce(struct timer_list *timer, unsigned long expires); extern void add_timer(struct timer_list *timer); extern int try_to_del_timer_sync(struct timer_list *timer); - -#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT) - extern int del_timer_sync(struct timer_list *timer); -#else -# define del_timer_sync(t) del_timer(t) -#endif +extern int del_timer_sync(struct timer_list *timer); #define del_singleshot_timer_sync(t) del_timer_sync(t) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 717fcb9fb14a..d9268bdbd733 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1365,7 +1365,6 @@ static inline void timer_sync_wait_running(struct timer_base *base) { } static inline void del_timer_wait_running(struct timer_list *timer) { } #endif -#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT) /** * del_timer_sync - deactivate a timer and wait for the handler to finish. * @timer: the timer to be deactivated @@ -1443,7 +1442,6 @@ int del_timer_sync(struct timer_list *timer) return ret; } EXPORT_SYMBOL(del_timer_sync); -#endif static void call_timer_fn(struct timer_list *timer, void (*fn)(struct timer_list *), From patchwork Tue Feb 20 19:24:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuxuan Luo X-Patchwork-Id: 1901641 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TfTr42T7Zz1yP6 for ; Wed, 21 Feb 2024 06:24:52 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1rcVjP-0008FS-6G; Tue, 20 Feb 2024 19:24:43 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1rcVjI-0008Df-L1 for kernel-team@lists.ubuntu.com; Tue, 20 Feb 2024 19:24:36 +0000 Received: from mail-pg1-f199.google.com (mail-pg1-f199.google.com [209.85.215.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 64A9F3F636 for ; Tue, 20 Feb 2024 19:24:36 +0000 (UTC) Received: by mail-pg1-f199.google.com with SMTP id 41be03b00d2f7-5cf555b2a53so5101748a12.1 for ; Tue, 20 Feb 2024 11:24:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708457074; x=1709061874; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aCc8+9T+3Oh9pYSdjiuo2P1UoeMXA3Wx7P9ymYJATKM=; b=QwQuHpXWX4xbDIfaI1z2wugvBjcocvjQA9GV93tAXONvQdyHlSFKq7ZMuFT0dsVFFr GbmebHwm6NHqyViOzVueMj344bmpT9eiHfxXA+R7d9qFFcvKRcEeXn4ps9AmtSxryMl4 FBL8Cb2kON6m6209GpzejYm+yLqfI/iysKx64+tWrfUcbdALR7WG5t4WNJd6DuR1WW8t VmtfCXdFMAabVS4wwaKovl2LSz3GPfMoRiylYoJ9j3MQnkMmO9efNDgVMsJhLFtVCUmK 6Rc4FweSrgoHwMou+KB3CxNm3zAsaACPNZJnFQPNuVNutigT91GqtisbSgDIFhV7xxnP 1F9A== X-Gm-Message-State: AOJu0YzYNhhQEdzWx3fFmSkdbtM0vQfWK7azq8WOQ1O5XD4L2TzmH18M HI+EBp7/PC++Ol49a9aHxvAw2VhH+M9FYD+RVt6GmxsnZnmR9R9T8VxJIOk4kDVAS/1qR4kKX00 cN+WEI/UrWFc71ujrn8huNHEK/U2iQ+xcv0gD6k7Jb1HKlIefydPGENe1Zbz/GE/yLSAg3jQ17k 3AFS/Vrpx7dQ== X-Received: by 2002:a17:902:ea0e:b0:1db:f15c:85c0 with SMTP id s14-20020a170902ea0e00b001dbf15c85c0mr8583046plg.33.1708457073997; Tue, 20 Feb 2024 11:24:33 -0800 (PST) X-Google-Smtp-Source: AGHT+IENHZH2nXSG8C0coQmRmd50iR6Wm0buEzn1XT8Gys35Zz0XvRJjS5jQvd2U8Q1b3Ja6TsWyZQ== X-Received: by 2002:a17:902:ea0e:b0:1db:f15c:85c0 with SMTP id s14-20020a170902ea0e00b001dbf15c85c0mr8583014plg.33.1708457073477; Tue, 20 Feb 2024 11:24:33 -0800 (PST) Received: from cache-ubuntu.hsd1.nj.comcast.net ([2001:67c:1562:8007::aac:4795]) by smtp.gmail.com with ESMTPSA id l21-20020a170902e2d500b001d9fcd343edsm6639440plc.208.2024.02.20.11.24.31 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Feb 2024 11:24:33 -0800 (PST) From: Yuxuan Luo To: kernel-team@lists.ubuntu.com Subject: [SRU][OEM-6.1][PATCH 2/8] timers: Update kernel-doc for various functions Date: Tue, 20 Feb 2024 14:24:15 -0500 Message-Id: <20240220192421.35003-3-yuxuan.luo@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240220192421.35003-1-yuxuan.luo@canonical.com> References: <20240220192421.35003-1-yuxuan.luo@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Thomas Gleixner The kernel-doc of timer related functions is partially uncomprehensible word salad. Rewrite it to make it useful. Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Jacob Keller Reviewed-by: Anna-Maria Behnsen Link: https://lore.kernel.org/r/20221123201624.828703870@linutronix.de (cherry picked from commit 14f043f1340bf30bc60af127bff39f55889fef26) CVE-2023-6039 Signed-off-by: Yuxuan Luo --- kernel/time/timer.c | 148 +++++++++++++++++++++++++++----------------- 1 file changed, 90 insertions(+), 58 deletions(-) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index d9268bdbd733..9d09a2a0ad70 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1121,14 +1121,16 @@ __mod_timer(struct timer_list *timer, unsigned long expires, unsigned int option } /** - * mod_timer_pending - modify a pending timer's timeout - * @timer: the pending timer to be modified - * @expires: new timeout in jiffies + * mod_timer_pending - Modify a pending timer's timeout + * @timer: The pending timer to be modified + * @expires: New absolute timeout in jiffies * - * mod_timer_pending() is the same for pending timers as mod_timer(), - * but will not re-activate and modify already deleted timers. + * mod_timer_pending() is the same for pending timers as mod_timer(), but + * will not activate inactive timers. * - * It is useful for unserialized use of timers. + * Return: + * * %0 - The timer was inactive and not modified + * * %1 - The timer was active and requeued to expire at @expires */ int mod_timer_pending(struct timer_list *timer, unsigned long expires) { @@ -1137,24 +1139,27 @@ int mod_timer_pending(struct timer_list *timer, unsigned long expires) EXPORT_SYMBOL(mod_timer_pending); /** - * mod_timer - modify a timer's timeout - * @timer: the timer to be modified - * @expires: new timeout in jiffies - * - * mod_timer() is a more efficient way to update the expire field of an - * active timer (if the timer is inactive it will be activated) + * mod_timer - Modify a timer's timeout + * @timer: The timer to be modified + * @expires: New absolute timeout in jiffies * * mod_timer(timer, expires) is equivalent to: * * del_timer(timer); timer->expires = expires; add_timer(timer); * + * mod_timer() is more efficient than the above open coded sequence. In + * case that the timer is inactive, the del_timer() part is a NOP. The + * timer is in any case activated with the new expiry time @expires. + * * Note that if there are multiple unserialized concurrent users of the * same timer, then mod_timer() is the only safe way to modify the timeout, * since add_timer() cannot modify an already running timer. * - * The function returns whether it has modified a pending timer or not. - * (ie. mod_timer() of an inactive timer returns 0, mod_timer() of an - * active timer returns 1.) + * Return: + * * %0 - The timer was inactive and started + * * %1 - The timer was active and requeued to expire at @expires or + * the timer was active and not modified because @expires did + * not change the effective expiry time */ int mod_timer(struct timer_list *timer, unsigned long expires) { @@ -1165,11 +1170,18 @@ EXPORT_SYMBOL(mod_timer); /** * timer_reduce - Modify a timer's timeout if it would reduce the timeout * @timer: The timer to be modified - * @expires: New timeout in jiffies + * @expires: New absolute timeout in jiffies * * timer_reduce() is very similar to mod_timer(), except that it will only - * modify a running timer if that would reduce the expiration time (it will - * start a timer that isn't running). + * modify an enqueued timer if that would reduce the expiration time. If + * @timer is not enqueued it starts the timer. + * + * Return: + * * %0 - The timer was inactive and started + * * %1 - The timer was active and requeued to expire at @expires or + * the timer was active and not modified because @expires + * did not change the effective expiry time such that the + * timer would expire earlier than already scheduled */ int timer_reduce(struct timer_list *timer, unsigned long expires) { @@ -1178,18 +1190,21 @@ int timer_reduce(struct timer_list *timer, unsigned long expires) EXPORT_SYMBOL(timer_reduce); /** - * add_timer - start a timer - * @timer: the timer to be added + * add_timer - Start a timer + * @timer: The timer to be started * - * The kernel will do a ->function(@timer) callback from the - * timer interrupt at the ->expires point in the future. The - * current time is 'jiffies'. + * Start @timer to expire at @timer->expires in the future. @timer->expires + * is the absolute expiry time measured in 'jiffies'. When the timer expires + * timer->function(timer) will be invoked from soft interrupt context. * - * The timer's ->expires, ->function fields must be set prior calling this - * function. + * The @timer->expires and @timer->function fields must be set prior + * to calling this function. + * + * If @timer->expires is already in the past @timer will be queued to + * expire at the next timer tick. * - * Timers with an ->expires field in the past will be executed in the next - * timer tick. + * This can only operate on an inactive timer. Attempts to invoke this on + * an active timer are rejected with a warning. */ void add_timer(struct timer_list *timer) { @@ -1199,11 +1214,13 @@ void add_timer(struct timer_list *timer) EXPORT_SYMBOL(add_timer); /** - * add_timer_on - start a timer on a particular CPU - * @timer: the timer to be added - * @cpu: the CPU to start it on + * add_timer_on - Start a timer on a particular CPU + * @timer: The timer to be started + * @cpu: The CPU to start it on + * + * Same as add_timer() except that it starts the timer on the given CPU. * - * This is not very scalable on SMP. Double adds are not possible. + * See add_timer() for further details. */ void add_timer_on(struct timer_list *timer, int cpu) { @@ -1238,15 +1255,18 @@ void add_timer_on(struct timer_list *timer, int cpu) EXPORT_SYMBOL_GPL(add_timer_on); /** - * del_timer - deactivate a timer. - * @timer: the timer to be deactivated - * - * del_timer() deactivates a timer - this works on both active and inactive - * timers. - * - * The function returns whether it has deactivated a pending timer or not. - * (ie. del_timer() of an inactive timer returns 0, del_timer() of an - * active timer returns 1.) + * del_timer - Deactivate a timer. + * @timer: The timer to be deactivated + * + * The function only deactivates a pending timer, but contrary to + * del_timer_sync() it does not take into account whether the timer's + * callback function is concurrently executed on a different CPU or not. + * It neither prevents rearming of the timer. If @timer can be rearmed + * concurrently then the return value of this function is meaningless. + * + * Return: + * * %0 - The timer was not pending + * * %1 - The timer was pending and deactivated */ int del_timer(struct timer_list *timer) { @@ -1268,10 +1288,19 @@ EXPORT_SYMBOL(del_timer); /** * try_to_del_timer_sync - Try to deactivate a timer - * @timer: timer to delete + * @timer: Timer to deactivate + * + * This function tries to deactivate a timer. On success the timer is not + * queued and the timer callback function is not running on any CPU. * - * This function tries to deactivate a timer. Upon successful (ret >= 0) - * exit the timer is not queued and the handler is not running on any CPU. + * This function does not guarantee that the timer cannot be rearmed right + * after dropping the base lock. That needs to be prevented by the calling + * code if necessary. + * + * Return: + * * %0 - The timer was not pending + * * %1 - The timer was pending and deactivated + * * %-1 - The timer callback function is running on a different CPU */ int try_to_del_timer_sync(struct timer_list *timer) { @@ -1366,23 +1395,19 @@ static inline void del_timer_wait_running(struct timer_list *timer) { } #endif /** - * del_timer_sync - deactivate a timer and wait for the handler to finish. - * @timer: the timer to be deactivated - * - * This function only differs from del_timer() on SMP: besides deactivating - * the timer it also makes sure the handler has finished executing on other - * CPUs. + * del_timer_sync - Deactivate a timer and wait for the handler to finish. + * @timer: The timer to be deactivated * * Synchronization rules: Callers must prevent restarting of the timer, * otherwise this function is meaningless. It must not be called from * interrupt contexts unless the timer is an irqsafe one. The caller must - * not hold locks which would prevent completion of the timer's - * handler. The timer's handler must not call add_timer_on(). Upon exit the - * timer is not queued and the handler is not running on any CPU. + * not hold locks which would prevent completion of the timer's callback + * function. The timer's handler must not call add_timer_on(). Upon exit + * the timer is not queued and the handler is not running on any CPU. * - * Note: For !irqsafe timers, you must not hold locks that are held in - * interrupt context while calling this function. Even if the lock has - * nothing to do with the timer in question. Here's why:: + * For !irqsafe timers, the caller must not hold locks that are held in + * interrupt context. Even if the lock has nothing to do with the timer in + * question. Here's why:: * * CPU0 CPU1 * ---- ---- @@ -1396,10 +1421,17 @@ static inline void del_timer_wait_running(struct timer_list *timer) { } * while (base->running_timer == mytimer); * * Now del_timer_sync() will never return and never release somelock. - * The interrupt on the other CPU is waiting to grab somelock but - * it has interrupted the softirq that CPU0 is waiting to finish. + * The interrupt on the other CPU is waiting to grab somelock but it has + * interrupted the softirq that CPU0 is waiting to finish. + * + * This function cannot guarantee that the timer is not rearmed again by + * some concurrent or preempting code, right after it dropped the base + * lock. If there is the possibility of a concurrent rearm then the return + * value of the function is meaningless. * - * The function returns whether it has deactivated a pending timer or not. + * Return: + * * %0 - The timer was not pending + * * %1 - The timer was pending and deactivated */ int del_timer_sync(struct timer_list *timer) { From patchwork Tue Feb 20 19:24:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuxuan Luo X-Patchwork-Id: 1901642 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TfTrF0bC1z1yP6 for ; Wed, 21 Feb 2024 06:25:01 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1rcVjS-0008HU-GJ; Tue, 20 Feb 2024 19:24:46 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1rcVjK-0008E1-Pv for kernel-team@lists.ubuntu.com; Tue, 20 Feb 2024 19:24:40 +0000 Received: from mail-pl1-f200.google.com (mail-pl1-f200.google.com [209.85.214.200]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 8F3673F68D for ; Tue, 20 Feb 2024 19:24:38 +0000 (UTC) Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-1db90f7b92bso53828305ad.0 for ; Tue, 20 Feb 2024 11:24:38 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708457076; x=1709061876; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YPV2gKtGxC45sSxmt04uAli51Skmg98dUcYYGKR+Nic=; b=dBLbnlz1MS7sIlmKrjomy2sotHxXvtaXe1/psXSmqp3MHI6tym+um2BiaCRbxqsOGu klEWV+AuH/1zI+shpRGwkSQ/zfy5XTHK6rjJf8PyV36DwH8sdhZ+VPu3/7AQ3/egGCqd oJi4eHsZWNLQm1Krm9JxP3KIzkNWKsUfI8jaHxpyb24Q3i9ku6ctAj3oJTxq9AUKmElR z+sMONaKE5b1y0BZIMNhwaZ7Gn/a+8pMhmUSFKx6l2+Duf+hd9dRRZcgGlyiKJgT54J5 KsYx2R2EI9Dw4zmK8BCdxahPz0j8VUm/Rtg0Kg+SktN2uCIATWnUL58GIj1uxFapB5ft HjOw== X-Gm-Message-State: AOJu0YxRLi+3Wqzwn2Ff0uXD78Jt/LyQRLIM79cHsUrkqnLy4iIjnpwH QQZEi2rHjcW1Scs5JXha9cNUMYEW7Qvy0zqzUMCOuDxg+SyIIvZy2cCpgadve+G8M7Y4ffcYUFj KvnyCxD9rMX5z4T+S+yFn0XqoPDv5x3zaW3v7uCEZU99Y/nqSQ/8rO67gPpmW8hCUKZcQYAtbZD ka/OF9ynkv4Q== X-Received: by 2002:a17:903:1205:b0:1d9:6091:6f3b with SMTP id l5-20020a170903120500b001d960916f3bmr17216591plh.47.1708457076146; Tue, 20 Feb 2024 11:24:36 -0800 (PST) X-Google-Smtp-Source: AGHT+IE63Xs/OEnI2HIWFwk3QiHsMJtCkDT/7nAXfziDQbCk021sWvyrVt4OQdoA8OkSPHCpdsZNEw== X-Received: by 2002:a17:903:1205:b0:1d9:6091:6f3b with SMTP id l5-20020a170903120500b001d960916f3bmr17216575plh.47.1708457075751; Tue, 20 Feb 2024 11:24:35 -0800 (PST) Received: from cache-ubuntu.hsd1.nj.comcast.net ([2001:67c:1562:8007::aac:4795]) by smtp.gmail.com with ESMTPSA id l21-20020a170902e2d500b001d9fcd343edsm6639440plc.208.2024.02.20.11.24.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Feb 2024 11:24:35 -0800 (PST) From: Yuxuan Luo To: kernel-team@lists.ubuntu.com Subject: [SRU][OEM-6.1][PATCH 3/8] timers: Rename del_timer_sync() to timer_delete_sync() Date: Tue, 20 Feb 2024 14:24:16 -0500 Message-Id: <20240220192421.35003-4-yuxuan.luo@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240220192421.35003-1-yuxuan.luo@canonical.com> References: <20240220192421.35003-1-yuxuan.luo@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Thomas Gleixner The timer related functions do not have a strict timer_ prefixed namespace which is really annoying. Rename del_timer_sync() to timer_delete_sync() and provide del_timer_sync() as a wrapper. Document that del_timer_sync() is not for new code. Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Steven Rostedt (Google) Reviewed-by: Jacob Keller Reviewed-by: Anna-Maria Behnsen Link: https://lore.kernel.org/r/20221123201624.954785441@linutronix.de (cherry picked from commit 9b13df3fb64ee95e2397585404e442afee2c7d4f) CVE-2023-6039 Signed-off-by: Yuxuan Luo --- include/linux/timer.h | 15 ++++++++++++++- kernel/time/timer.c | 18 +++++++++--------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/include/linux/timer.h b/include/linux/timer.h index 82bb2e4d3b7c..6d18f04ad703 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -183,7 +183,20 @@ extern int timer_reduce(struct timer_list *timer, unsigned long expires); extern void add_timer(struct timer_list *timer); extern int try_to_del_timer_sync(struct timer_list *timer); -extern int del_timer_sync(struct timer_list *timer); +extern int timer_delete_sync(struct timer_list *timer); + +/** + * del_timer_sync - Delete a pending timer and wait for a running callback + * @timer: The timer to be deleted + * + * See timer_delete_sync() for detailed explanation. + * + * Do not use in new code. Use timer_delete_sync() instead. + */ +static inline int del_timer_sync(struct timer_list *timer) +{ + return timer_delete_sync(timer); +} #define del_singleshot_timer_sync(t) del_timer_sync(t) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 9d09a2a0ad70..59469897432b 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1083,7 +1083,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, unsigned int option /* * We are trying to schedule the timer on the new base. * However we can't change timer's base while it is running, - * otherwise del_timer_sync() can't detect that the timer's + * otherwise timer_delete_sync() can't detect that the timer's * handler yet has not finished. This also guarantees that the * timer is serialized wrt itself. */ @@ -1259,7 +1259,7 @@ EXPORT_SYMBOL_GPL(add_timer_on); * @timer: The timer to be deactivated * * The function only deactivates a pending timer, but contrary to - * del_timer_sync() it does not take into account whether the timer's + * timer_delete_sync() it does not take into account whether the timer's * callback function is concurrently executed on a different CPU or not. * It neither prevents rearming of the timer. If @timer can be rearmed * concurrently then the return value of this function is meaningless. @@ -1395,7 +1395,7 @@ static inline void del_timer_wait_running(struct timer_list *timer) { } #endif /** - * del_timer_sync - Deactivate a timer and wait for the handler to finish. + * timer_delete_sync - Deactivate a timer and wait for the handler to finish. * @timer: The timer to be deactivated * * Synchronization rules: Callers must prevent restarting of the timer, @@ -1417,10 +1417,10 @@ static inline void del_timer_wait_running(struct timer_list *timer) { } * spin_lock_irq(somelock); * * spin_lock(somelock); - * del_timer_sync(mytimer); + * timer_delete_sync(mytimer); * while (base->running_timer == mytimer); * - * Now del_timer_sync() will never return and never release somelock. + * Now timer_delete_sync() will never return and never release somelock. * The interrupt on the other CPU is waiting to grab somelock but it has * interrupted the softirq that CPU0 is waiting to finish. * @@ -1433,7 +1433,7 @@ static inline void del_timer_wait_running(struct timer_list *timer) { } * * %0 - The timer was not pending * * %1 - The timer was pending and deactivated */ -int del_timer_sync(struct timer_list *timer) +int timer_delete_sync(struct timer_list *timer) { int ret; @@ -1473,7 +1473,7 @@ int del_timer_sync(struct timer_list *timer) return ret; } -EXPORT_SYMBOL(del_timer_sync); +EXPORT_SYMBOL(timer_delete_sync); static void call_timer_fn(struct timer_list *timer, void (*fn)(struct timer_list *), @@ -1495,8 +1495,8 @@ static void call_timer_fn(struct timer_list *timer, #endif /* * Couple the lock chain with the lock chain at - * del_timer_sync() by acquiring the lock_map around the fn() - * call here and in del_timer_sync(). + * timer_delete_sync() by acquiring the lock_map around the fn() + * call here and in timer_delete_sync(). */ lock_map_acquire(&lockdep_map); From patchwork Tue Feb 20 19:24:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuxuan Luo X-Patchwork-Id: 1901643 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TfTrJ1tLCz1yP6 for ; Wed, 21 Feb 2024 06:25:04 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1rcVjV-0008Kx-Vq; Tue, 20 Feb 2024 19:24:50 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1rcVjM-0008EO-DL for kernel-team@lists.ubuntu.com; Tue, 20 Feb 2024 19:24:40 +0000 Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 31BF63F83F for ; Tue, 20 Feb 2024 19:24:40 +0000 (UTC) Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-1dc1db2fb48so7847105ad.0 for ; Tue, 20 Feb 2024 11:24:40 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708457078; x=1709061878; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9Pmt0BEubYQw0G1SFAbry/PDi5nK2/kzfMBz7hxVVt8=; b=eSjkT+CUleTvm+QmzP0Y30jqFtzXDu8o4iaJYSN3HcOnqE/Rt8v6IhttaNSabloUE7 XsoajX5UWQLmz8TI5vqRV8nhDD7/VobQoVnmDJyUcAKgKm71zNFtxDx2tn8pbM2OJQBr lVSGD6R2dkq6tNW140A6VH6jMErP7LOsrcjZm5EbnOOCbpLdOQ8qIEO4PmGSdKEnMb7a o/xfoh3Q4vl6z5SiZ0HyGAFk8EMa7PnklMrgFCWwdOe3MfjBdRtHC63KJDWkhQnZIjkc SUM26ghTE742lk3FbBu56Bliu34KwfbWdF7f01DrVEhhTlZtXYfTC0jMzK9fCYj8hSOm HttA== X-Gm-Message-State: AOJu0Yx5hXbGvpZNNYf8UwfEYSJ6xHAvs/V1UQXEUf+wndQdo66V6qDD K2G+mGCHFwTDq0ff0DTHkYVrbKI8/VcgdA+2psZ51PJX5Derq8ccZ1qzqiWNTC8etcd5M0vjtX1 X50QIG6aU1Zs7XwJLHKyMCzfmEoqkjAL6zoRhprnCyfqZdI8NGJoCR1dzvwdeteg3GMQZuzVtxR LZQQy22K65dw== X-Received: by 2002:a17:902:684a:b0:1db:730c:c077 with SMTP id f10-20020a170902684a00b001db730cc077mr14052699pln.58.1708457078405; Tue, 20 Feb 2024 11:24:38 -0800 (PST) X-Google-Smtp-Source: AGHT+IHej3gIdq7ykxBlM9w0fQnZ87zmc5w/2SmNuQ5Y0NTH5v25aBqAX4lpmOPd8OcOPv+bQm+0Og== X-Received: by 2002:a17:902:684a:b0:1db:730c:c077 with SMTP id f10-20020a170902684a00b001db730cc077mr14052693pln.58.1708457078008; Tue, 20 Feb 2024 11:24:38 -0800 (PST) Received: from cache-ubuntu.hsd1.nj.comcast.net ([2001:67c:1562:8007::aac:4795]) by smtp.gmail.com with ESMTPSA id l21-20020a170902e2d500b001d9fcd343edsm6639440plc.208.2024.02.20.11.24.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Feb 2024 11:24:37 -0800 (PST) From: Yuxuan Luo To: kernel-team@lists.ubuntu.com Subject: [SRU][OEM-6.1][PATCH 4/8] timers: Rename del_timer() to timer_delete() Date: Tue, 20 Feb 2024 14:24:17 -0500 Message-Id: <20240220192421.35003-5-yuxuan.luo@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240220192421.35003-1-yuxuan.luo@canonical.com> References: <20240220192421.35003-1-yuxuan.luo@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Thomas Gleixner The timer related functions do not have a strict timer_ prefixed namespace which is really annoying. Rename del_timer() to timer_delete() and provide del_timer() as a wrapper. Document that del_timer() is not for new code. Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Steven Rostedt (Google) Reviewed-by: Jacob Keller Reviewed-by: Anna-Maria Behnsen Link: https://lore.kernel.org/r/20221123201625.015535022@linutronix.de (backported from commit bb663f0f3c396c6d05f6c5eeeea96ced20ff112e) [yuxuan.luo: ignored the conflict and added the new content] CVE-2023-6039 Signed-off-by: Yuxuan Luo --- include/linux/timer.h | 15 ++++++++++++++- kernel/time/timer.c | 6 +++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/linux/timer.h b/include/linux/timer.h index 6d18f04ad703..d5aaf3a7adf0 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -169,7 +169,6 @@ static inline int timer_pending(const struct timer_list * timer) } extern void add_timer_on(struct timer_list *timer, int cpu); -extern int del_timer(struct timer_list * timer); extern int mod_timer(struct timer_list *timer, unsigned long expires); extern int mod_timer_pending(struct timer_list *timer, unsigned long expires); extern int timer_reduce(struct timer_list *timer, unsigned long expires); @@ -184,6 +183,7 @@ extern void add_timer(struct timer_list *timer); extern int try_to_del_timer_sync(struct timer_list *timer); extern int timer_delete_sync(struct timer_list *timer); +extern int timer_delete(struct timer_list *timer); /** * del_timer_sync - Delete a pending timer and wait for a running callback @@ -200,6 +200,19 @@ static inline int del_timer_sync(struct timer_list *timer) #define del_singleshot_timer_sync(t) del_timer_sync(t) +/** + * del_timer - Delete a pending timer + * @timer: The timer to be deleted + * + * See timer_delete() for detailed explanation. + * + * Do not use in new code. Use timer_delete() instead. + */ +static inline int del_timer(struct timer_list *timer) +{ + return timer_delete(timer); +} + extern void init_timers(void); struct hrtimer; extern enum hrtimer_restart it_real_fn(struct hrtimer *); diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 59469897432b..63d5f94fb7c1 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1255,7 +1255,7 @@ void add_timer_on(struct timer_list *timer, int cpu) EXPORT_SYMBOL_GPL(add_timer_on); /** - * del_timer - Deactivate a timer. + * timer_delete - Deactivate a timer * @timer: The timer to be deactivated * * The function only deactivates a pending timer, but contrary to @@ -1268,7 +1268,7 @@ EXPORT_SYMBOL_GPL(add_timer_on); * * %0 - The timer was not pending * * %1 - The timer was pending and deactivated */ -int del_timer(struct timer_list *timer) +int timer_delete(struct timer_list *timer) { struct timer_base *base; unsigned long flags; @@ -1284,7 +1284,7 @@ int del_timer(struct timer_list *timer) return ret; } -EXPORT_SYMBOL(del_timer); +EXPORT_SYMBOL(timer_delete); /** * try_to_del_timer_sync - Try to deactivate a timer From patchwork Tue Feb 20 19:24:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuxuan Luo X-Patchwork-Id: 1901645 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TfTrd5qnFz20Qg for ; Wed, 21 Feb 2024 06:25:21 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1rcVjn-0000FD-VR; Tue, 20 Feb 2024 19:25:08 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1rcVjP-0008Fo-IK for kernel-team@lists.ubuntu.com; Tue, 20 Feb 2024 19:24:43 +0000 Received: from mail-pl1-f200.google.com (mail-pl1-f200.google.com [209.85.214.200]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 2B5753F636 for ; Tue, 20 Feb 2024 19:24:43 +0000 (UTC) Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-1dbf266b99cso17988355ad.2 for ; Tue, 20 Feb 2024 11:24:43 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708457081; x=1709061881; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2KhcWi+w1ucmsDtF3qQoZOZqxhKSKfxz4gmJhFF7Gn0=; b=RlBnkTpBv13EIJJD4JUCeVD6XU9url2U4oWMu1lc0YoYajYUyx/6HhwXQtK7pXJy1u tddQQOtru/VBoXkweZaB1GNOSgfE5dpi5xWY/bAGw29bPQvIMzL1yklWkJrSHnJu01lw VlPjm8Ke9O6CXPsaXuitHSJ4YFpXGzVyWvcDDoI7NO6xWFfsQ4fI1Y6I1sxOaKCAknui PrecAjdZCtNFCq5Fjp7r2Pc3Vtnq4/po26pDHB2B4PF5pUh091B14bVfqDuJpjTkO+fc 7I1vB1h7Rx6vzyHr5eA6F/fX2Q6zLbJYMiMUTckYiUbgnUGJIEJh5AZ3OxEP75+D/m9F bMSA== X-Gm-Message-State: AOJu0Yx+FooXqaBbLEuqYfFey81EUuEg4xZNiXav1JlKel3OlA7sZ4n2 NQngJardqj3OMseDqsnw78Ni4V4glnBd2+WcVX2s8p2XFJPmP/n6qO/Xgs27TUgc8tZZJHGgY+I 9y5R4vHkVstFSLfwAuW6tDgJNv5xQwlIcVcpSpalqoL1Oq5xuNLJSkeXhOsoqVUuFlKt3KvdXV0 0lkbTU/Nj4HA== X-Received: by 2002:a17:903:2342:b0:1db:d9ed:f91d with SMTP id c2-20020a170903234200b001dbd9edf91dmr9954837plh.33.1708457080804; Tue, 20 Feb 2024 11:24:40 -0800 (PST) X-Google-Smtp-Source: AGHT+IEPghCHZm7MuHqXnxxRV9IZ0DRNx+n/dwEXcb8P4baKLe8xWbD22d8/llcFDccRG5L8oP7Q+w== X-Received: by 2002:a17:903:2342:b0:1db:d9ed:f91d with SMTP id c2-20020a170903234200b001dbd9edf91dmr9954808plh.33.1708457080296; Tue, 20 Feb 2024 11:24:40 -0800 (PST) Received: from cache-ubuntu.hsd1.nj.comcast.net ([2001:67c:1562:8007::aac:4795]) by smtp.gmail.com with ESMTPSA id l21-20020a170902e2d500b001d9fcd343edsm6639440plc.208.2024.02.20.11.24.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Feb 2024 11:24:39 -0800 (PST) From: Yuxuan Luo To: kernel-team@lists.ubuntu.com Subject: [SRU][OEM-6.1][PATCH 5/8] timers: Split [try_to_]del_timer[_sync]() to prepare for shutdown mode Date: Tue, 20 Feb 2024 14:24:18 -0500 Message-Id: <20240220192421.35003-6-yuxuan.luo@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240220192421.35003-1-yuxuan.luo@canonical.com> References: <20240220192421.35003-1-yuxuan.luo@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Thomas Gleixner Tearing down timers which have circular dependencies to other functionality, e.g. workqueues, where the timer can schedule work and work can arm timers, is not trivial. In those cases it is desired to shutdown the timer in a way which prevents rearming of the timer. The mechanism to do so is to set timer->function to NULL and use this as an indicator for the timer arming functions to ignore the (re)arm request. Split the inner workings of try_do_del_timer_sync(), del_timer_sync() and del_timer() into helper functions to prepare for implementing the shutdown functionality. No functional change. Co-developed-by: Steven Rostedt Signed-off-by: Steven Rostedt Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Jacob Keller Reviewed-by: Anna-Maria Behnsen Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org Link: https://lore.kernel.org/r/20221123201625.195147423@linutronix.de (cherry picked from commit 8553b5f2774a66b1f293b7d783934210afb8f23c) CVE-2023-6039 Signed-off-by: Yuxuan Luo --- kernel/time/timer.c | 145 ++++++++++++++++++++++++++++---------------- 1 file changed, 93 insertions(+), 52 deletions(-) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 63d5f94fb7c1..8296cdb1b6ff 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1255,20 +1255,14 @@ void add_timer_on(struct timer_list *timer, int cpu) EXPORT_SYMBOL_GPL(add_timer_on); /** - * timer_delete - Deactivate a timer + * __timer_delete - Internal function: Deactivate a timer * @timer: The timer to be deactivated * - * The function only deactivates a pending timer, but contrary to - * timer_delete_sync() it does not take into account whether the timer's - * callback function is concurrently executed on a different CPU or not. - * It neither prevents rearming of the timer. If @timer can be rearmed - * concurrently then the return value of this function is meaningless. - * * Return: * * %0 - The timer was not pending * * %1 - The timer was pending and deactivated */ -int timer_delete(struct timer_list *timer) +static int __timer_delete(struct timer_list *timer) { struct timer_base *base; unsigned long flags; @@ -1284,25 +1278,37 @@ int timer_delete(struct timer_list *timer) return ret; } -EXPORT_SYMBOL(timer_delete); /** - * try_to_del_timer_sync - Try to deactivate a timer - * @timer: Timer to deactivate + * timer_delete - Deactivate a timer + * @timer: The timer to be deactivated * - * This function tries to deactivate a timer. On success the timer is not - * queued and the timer callback function is not running on any CPU. + * The function only deactivates a pending timer, but contrary to + * timer_delete_sync() it does not take into account whether the timer's + * callback function is concurrently executed on a different CPU or not. + * It neither prevents rearming of the timer. If @timer can be rearmed + * concurrently then the return value of this function is meaningless. * - * This function does not guarantee that the timer cannot be rearmed right - * after dropping the base lock. That needs to be prevented by the calling - * code if necessary. + * Return: + * * %0 - The timer was not pending + * * %1 - The timer was pending and deactivated + */ +int timer_delete(struct timer_list *timer) +{ + return __timer_delete(timer); +} +EXPORT_SYMBOL(timer_delete); + +/** + * __try_to_del_timer_sync - Internal function: Try to deactivate a timer + * @timer: Timer to deactivate * * Return: * * %0 - The timer was not pending * * %1 - The timer was pending and deactivated * * %-1 - The timer callback function is running on a different CPU */ -int try_to_del_timer_sync(struct timer_list *timer) +static int __try_to_del_timer_sync(struct timer_list *timer) { struct timer_base *base; unsigned long flags; @@ -1319,6 +1325,27 @@ int try_to_del_timer_sync(struct timer_list *timer) return ret; } + +/** + * try_to_del_timer_sync - Try to deactivate a timer + * @timer: Timer to deactivate + * + * This function tries to deactivate a timer. On success the timer is not + * queued and the timer callback function is not running on any CPU. + * + * This function does not guarantee that the timer cannot be rearmed right + * after dropping the base lock. That needs to be prevented by the calling + * code if necessary. + * + * Return: + * * %0 - The timer was not pending + * * %1 - The timer was pending and deactivated + * * %-1 - The timer callback function is running on a different CPU + */ +int try_to_del_timer_sync(struct timer_list *timer) +{ + return __try_to_del_timer_sync(timer); +} EXPORT_SYMBOL(try_to_del_timer_sync); #ifdef CONFIG_PREEMPT_RT @@ -1395,45 +1422,15 @@ static inline void del_timer_wait_running(struct timer_list *timer) { } #endif /** - * timer_delete_sync - Deactivate a timer and wait for the handler to finish. + * __timer_delete_sync - Internal function: Deactivate a timer and wait + * for the handler to finish. * @timer: The timer to be deactivated * - * Synchronization rules: Callers must prevent restarting of the timer, - * otherwise this function is meaningless. It must not be called from - * interrupt contexts unless the timer is an irqsafe one. The caller must - * not hold locks which would prevent completion of the timer's callback - * function. The timer's handler must not call add_timer_on(). Upon exit - * the timer is not queued and the handler is not running on any CPU. - * - * For !irqsafe timers, the caller must not hold locks that are held in - * interrupt context. Even if the lock has nothing to do with the timer in - * question. Here's why:: - * - * CPU0 CPU1 - * ---- ---- - * - * call_timer_fn(); - * base->running_timer = mytimer; - * spin_lock_irq(somelock); - * - * spin_lock(somelock); - * timer_delete_sync(mytimer); - * while (base->running_timer == mytimer); - * - * Now timer_delete_sync() will never return and never release somelock. - * The interrupt on the other CPU is waiting to grab somelock but it has - * interrupted the softirq that CPU0 is waiting to finish. - * - * This function cannot guarantee that the timer is not rearmed again by - * some concurrent or preempting code, right after it dropped the base - * lock. If there is the possibility of a concurrent rearm then the return - * value of the function is meaningless. - * * Return: * * %0 - The timer was not pending * * %1 - The timer was pending and deactivated */ -int timer_delete_sync(struct timer_list *timer) +static int __timer_delete_sync(struct timer_list *timer) { int ret; @@ -1453,7 +1450,7 @@ int timer_delete_sync(struct timer_list *timer) * don't use it in hardirq context, because it * could lead to deadlock. */ - WARN_ON(in_irq() && !(timer->flags & TIMER_IRQSAFE)); + WARN_ON(in_hardirq() && !(timer->flags & TIMER_IRQSAFE)); /* * Must be able to sleep on PREEMPT_RT because of the slowpath in @@ -1463,7 +1460,7 @@ int timer_delete_sync(struct timer_list *timer) lockdep_assert_preemption_enabled(); do { - ret = try_to_del_timer_sync(timer); + ret = __try_to_del_timer_sync(timer); if (unlikely(ret < 0)) { del_timer_wait_running(timer); @@ -1473,6 +1470,50 @@ int timer_delete_sync(struct timer_list *timer) return ret; } + +/** + * timer_delete_sync - Deactivate a timer and wait for the handler to finish. + * @timer: The timer to be deactivated + * + * Synchronization rules: Callers must prevent restarting of the timer, + * otherwise this function is meaningless. It must not be called from + * interrupt contexts unless the timer is an irqsafe one. The caller must + * not hold locks which would prevent completion of the timer's callback + * function. The timer's handler must not call add_timer_on(). Upon exit + * the timer is not queued and the handler is not running on any CPU. + * + * For !irqsafe timers, the caller must not hold locks that are held in + * interrupt context. Even if the lock has nothing to do with the timer in + * question. Here's why:: + * + * CPU0 CPU1 + * ---- ---- + * + * call_timer_fn(); + * base->running_timer = mytimer; + * spin_lock_irq(somelock); + * + * spin_lock(somelock); + * timer_delete_sync(mytimer); + * while (base->running_timer == mytimer); + * + * Now timer_delete_sync() will never return and never release somelock. + * The interrupt on the other CPU is waiting to grab somelock but it has + * interrupted the softirq that CPU0 is waiting to finish. + * + * This function cannot guarantee that the timer is not rearmed again by + * some concurrent or preempting code, right after it dropped the base + * lock. If there is the possibility of a concurrent rearm then the return + * value of the function is meaningless. + * + * Return: + * * %0 - The timer was not pending + * * %1 - The timer was pending and deactivated + */ +int timer_delete_sync(struct timer_list *timer) +{ + return __timer_delete_sync(timer); +} EXPORT_SYMBOL(timer_delete_sync); static void call_timer_fn(struct timer_list *timer, From patchwork Tue Feb 20 19:24:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuxuan Luo X-Patchwork-Id: 1901644 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TfTrS3m7rz20Qg for ; Wed, 21 Feb 2024 06:25:12 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1rcVjd-0008Ot-Px; Tue, 20 Feb 2024 19:24:59 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1rcVjR-0008GS-J9 for kernel-team@lists.ubuntu.com; Tue, 20 Feb 2024 19:24:45 +0000 Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 65FCA3FA51 for ; Tue, 20 Feb 2024 19:24:45 +0000 (UTC) Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-1dbde77b6f1so29692095ad.1 for ; Tue, 20 Feb 2024 11:24:45 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708457083; x=1709061883; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Zz+nAa8BY8EbLRyzMnZC8rtTYU1KKoxo+TrUO5fbmew=; b=LiFm6fOL0QFrM3Ql2MfXmAwg3Gti0vL16uupGA9g/o7HspiM8LlrnxqoBem9Ny5sg4 EGOMn9Xcgz3oySD6QD2hQedBcmTYut26+fOXc6JJlDd3poB/haEqA/7A9T+Pf8B5FS20 8w3QPXJughxeIuDw8HjGw6937Fy4vzGTVggbMgz06bl4D0r8phonJhBOMS2Sw9DY8dRk lQhnWGCcVQLxJToz+eUXGjAXPjCdkHRdFg/iIVr5itykac9VHFpKQkpRTF4j+y+ZThyu q8EaYmFVy0VwKCnQHaFkwsdXsuKbtDjZBrwKRYUax1tD9diKNvbLbPXBkjJNlUOfitbp 6LLw== X-Gm-Message-State: AOJu0YyJvPEWFCeYiVC1/kzZmqWs4w7vLZLQK/r6qcnhAeNnkXLYxOSI rtLCFuv5RqUjnbgXPep2NSGc8RzTfDHgVsOTL/XmkMpSv7gOMLNlAe7NzV/FQYn9qSfTnOD4/Bk bir4WH857ETp5j9Dr4dCVUGJ0gjzYzI1mHz9Om9u1Q5Yt5pp9PVj5/aZbIyn+l+MgNst8IIsJsb 1aZJgVnT3yUg== X-Received: by 2002:a17:902:c402:b0:1db:3a22:1fd6 with SMTP id k2-20020a170902c40200b001db3a221fd6mr17980157plk.66.1708457082991; Tue, 20 Feb 2024 11:24:42 -0800 (PST) X-Google-Smtp-Source: AGHT+IHjb1+3YIkKQfz59vaukTL98pwCDniWqEkSMg0EJxRvihQvBLSqLgLsDYSzr8qpTTMq86l2og== X-Received: by 2002:a17:902:c402:b0:1db:3a22:1fd6 with SMTP id k2-20020a170902c40200b001db3a221fd6mr17980138plk.66.1708457082548; Tue, 20 Feb 2024 11:24:42 -0800 (PST) Received: from cache-ubuntu.hsd1.nj.comcast.net ([2001:67c:1562:8007::aac:4795]) by smtp.gmail.com with ESMTPSA id l21-20020a170902e2d500b001d9fcd343edsm6639440plc.208.2024.02.20.11.24.40 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Feb 2024 11:24:42 -0800 (PST) From: Yuxuan Luo To: kernel-team@lists.ubuntu.com Subject: [SRU][OEM-6.1][PATCH 6/8] timers: Add shutdown mechanism to the internal functions Date: Tue, 20 Feb 2024 14:24:19 -0500 Message-Id: <20240220192421.35003-7-yuxuan.luo@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240220192421.35003-1-yuxuan.luo@canonical.com> References: <20240220192421.35003-1-yuxuan.luo@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Thomas Gleixner Tearing down timers which have circular dependencies to other functionality, e.g. workqueues, where the timer can schedule work and work can arm timers, is not trivial. In those cases it is desired to shutdown the timer in a way which prevents rearming of the timer. The mechanism to do so is to set timer->function to NULL and use this as an indicator for the timer arming functions to ignore the (re)arm request. Add a shutdown argument to the relevant internal functions which makes the actual deactivation code set timer->function to NULL which in turn prevents rearming of the timer. Co-developed-by: Steven Rostedt Signed-off-by: Steven Rostedt Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Jacob Keller Reviewed-by: Anna-Maria Behnsen Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org Link: https://lore.kernel.org/r/20221123201625.253883224@linutronix.de (cherry picked from commit 0cc04e80458a822300b93f82ed861a513edde194) CVE-2023-6039 Signed-off-by: Yuxuan Luo --- kernel/time/timer.c | 62 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 8296cdb1b6ff..9035e336456b 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1257,12 +1257,19 @@ EXPORT_SYMBOL_GPL(add_timer_on); /** * __timer_delete - Internal function: Deactivate a timer * @timer: The timer to be deactivated + * @shutdown: If true, this indicates that the timer is about to be + * shutdown permanently. + * + * If @shutdown is true then @timer->function is set to NULL under the + * timer base lock which prevents further rearming of the time. In that + * case any attempt to rearm @timer after this function returns will be + * silently ignored. * * Return: * * %0 - The timer was not pending * * %1 - The timer was pending and deactivated */ -static int __timer_delete(struct timer_list *timer) +static int __timer_delete(struct timer_list *timer, bool shutdown) { struct timer_base *base; unsigned long flags; @@ -1270,9 +1277,22 @@ static int __timer_delete(struct timer_list *timer) debug_assert_init(timer); - if (timer_pending(timer)) { + /* + * If @shutdown is set then the lock has to be taken whether the + * timer is pending or not to protect against a concurrent rearm + * which might hit between the lockless pending check and the lock + * aquisition. By taking the lock it is ensured that such a newly + * enqueued timer is dequeued and cannot end up with + * timer->function == NULL in the expiry code. + * + * If timer->function is currently executed, then this makes sure + * that the callback cannot requeue the timer. + */ + if (timer_pending(timer) || shutdown) { base = lock_timer_base(timer, &flags); ret = detach_if_pending(timer, base, true); + if (shutdown) + timer->function = NULL; raw_spin_unlock_irqrestore(&base->lock, flags); } @@ -1295,20 +1315,31 @@ static int __timer_delete(struct timer_list *timer) */ int timer_delete(struct timer_list *timer) { - return __timer_delete(timer); + return __timer_delete(timer, false); } EXPORT_SYMBOL(timer_delete); /** * __try_to_del_timer_sync - Internal function: Try to deactivate a timer * @timer: Timer to deactivate + * @shutdown: If true, this indicates that the timer is about to be + * shutdown permanently. + * + * If @shutdown is true then @timer->function is set to NULL under the + * timer base lock which prevents further rearming of the timer. Any + * attempt to rearm @timer after this function returns will be silently + * ignored. + * + * This function cannot guarantee that the timer cannot be rearmed + * right after dropping the base lock if @shutdown is false. That + * needs to be prevented by the calling code if necessary. * * Return: * * %0 - The timer was not pending * * %1 - The timer was pending and deactivated * * %-1 - The timer callback function is running on a different CPU */ -static int __try_to_del_timer_sync(struct timer_list *timer) +static int __try_to_del_timer_sync(struct timer_list *timer, bool shutdown) { struct timer_base *base; unsigned long flags; @@ -1320,6 +1351,8 @@ static int __try_to_del_timer_sync(struct timer_list *timer) if (base->running_timer != timer) ret = detach_if_pending(timer, base, true); + if (shutdown) + timer->function = NULL; raw_spin_unlock_irqrestore(&base->lock, flags); @@ -1344,7 +1377,7 @@ static int __try_to_del_timer_sync(struct timer_list *timer) */ int try_to_del_timer_sync(struct timer_list *timer) { - return __try_to_del_timer_sync(timer); + return __try_to_del_timer_sync(timer, false); } EXPORT_SYMBOL(try_to_del_timer_sync); @@ -1425,12 +1458,25 @@ static inline void del_timer_wait_running(struct timer_list *timer) { } * __timer_delete_sync - Internal function: Deactivate a timer and wait * for the handler to finish. * @timer: The timer to be deactivated + * @shutdown: If true, @timer->function will be set to NULL under the + * timer base lock which prevents rearming of @timer + * + * If @shutdown is not set the timer can be rearmed later. If the timer can + * be rearmed concurrently, i.e. after dropping the base lock then the + * return value is meaningless. + * + * If @shutdown is set then @timer->function is set to NULL under timer + * base lock which prevents rearming of the timer. Any attempt to rearm + * a shutdown timer is silently ignored. + * + * If the timer should be reused after shutdown it has to be initialized + * again. * * Return: * * %0 - The timer was not pending * * %1 - The timer was pending and deactivated */ -static int __timer_delete_sync(struct timer_list *timer) +static int __timer_delete_sync(struct timer_list *timer, bool shutdown) { int ret; @@ -1460,7 +1506,7 @@ static int __timer_delete_sync(struct timer_list *timer) lockdep_assert_preemption_enabled(); do { - ret = __try_to_del_timer_sync(timer); + ret = __try_to_del_timer_sync(timer, shutdown); if (unlikely(ret < 0)) { del_timer_wait_running(timer); @@ -1512,7 +1558,7 @@ static int __timer_delete_sync(struct timer_list *timer) */ int timer_delete_sync(struct timer_list *timer) { - return __timer_delete_sync(timer); + return __timer_delete_sync(timer, false); } EXPORT_SYMBOL(timer_delete_sync); From patchwork Tue Feb 20 19:24:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuxuan Luo X-Patchwork-Id: 1901646 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TfTs93hhdz20Qg for ; Wed, 21 Feb 2024 06:25:49 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1rcVkI-0000cK-CX; Tue, 20 Feb 2024 19:25:38 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1rcVjU-0008Ic-Pe for kernel-team@lists.ubuntu.com; Tue, 20 Feb 2024 19:24:49 +0000 Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id A6B223F636 for ; Tue, 20 Feb 2024 19:24:47 +0000 (UTC) Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-1dbde77b6f1so29692495ad.1 for ; Tue, 20 Feb 2024 11:24:47 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708457085; x=1709061885; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=H46tP/zD+ts38Nn1wXu3XkaOghwpa8RwHK/zx/mWEEM=; b=BXkn3+Y15hfPl+ZRUngLI7+yRwDyABz1CuVY100Uj4pmumLkLfdr7iG5PszmdyZpse 4pa+D9MSuACNFFWil54ijdizjM9aQqdclx8YAUtE6G2oR4DLJIICMN7z4RCn6qxV3Ep0 aq19xFqO0mcZT3QDXhzkbzWfWk5QNu5FX6sJNBo685PbeXBynvrcNGHIGKfBL2rkUo0A x2H3HN9gXMmdoLeLDBI6g0mllA/vDMcwYUD7x1b1c9zoDIW0QivhfiJvaM7xs1uELbop rHWUOkBhMMa4UI3PbNGzAvbVskdi7RQ7Hpq8XhmMwEhs7FtpO1OHnYXoH1Lo2vXxd8NZ UjDw== X-Gm-Message-State: AOJu0YwOaZRdq14iJw58jVuBoSCXVuz10vsK8Dco6O7/DAQUdkf6Rn0j VZEcEP3XPQn9fh1MJ3iIQbawnmUn1xQaffEqWUZ2nqP/p246tMlizKEKX+kH+oxeebqmoEvRb1m cTGt0FRZOqjwxoCRx6uI4do+sBtFyOM2CrcQRp92jbJD9pbezaVlR2V0Vm0zsqrHwWd8xv/yX24 aJK6mQoAya2w== X-Received: by 2002:a17:903:41c6:b0:1dc:1d34:c748 with SMTP id u6-20020a17090341c600b001dc1d34c748mr2304836ple.64.1708457085271; Tue, 20 Feb 2024 11:24:45 -0800 (PST) X-Google-Smtp-Source: AGHT+IGwZLSh9vmEvq8TMn1J1Rin0Ri2U/iuz2fmS4+mA23ulHCmc3RSYifAqhPEyPeSWvikw4k/Jw== X-Received: by 2002:a17:903:41c6:b0:1dc:1d34:c748 with SMTP id u6-20020a17090341c600b001dc1d34c748mr2304815ple.64.1708457084837; Tue, 20 Feb 2024 11:24:44 -0800 (PST) Received: from cache-ubuntu.hsd1.nj.comcast.net ([2001:67c:1562:8007::aac:4795]) by smtp.gmail.com with ESMTPSA id l21-20020a170902e2d500b001d9fcd343edsm6639440plc.208.2024.02.20.11.24.43 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Feb 2024 11:24:44 -0800 (PST) From: Yuxuan Luo To: kernel-team@lists.ubuntu.com Subject: [SRU][OEM-6.1][PATCH 7/8] timers: Provide timer_shutdown[_sync]() Date: Tue, 20 Feb 2024 14:24:20 -0500 Message-Id: <20240220192421.35003-8-yuxuan.luo@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240220192421.35003-1-yuxuan.luo@canonical.com> References: <20240220192421.35003-1-yuxuan.luo@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Thomas Gleixner Tearing down timers which have circular dependencies to other functionality, e.g. workqueues, where the timer can schedule work and work can arm timers, is not trivial. In those cases it is desired to shutdown the timer in a way which prevents rearming of the timer. The mechanism to do so is to set timer->function to NULL and use this as an indicator for the timer arming functions to ignore the (re)arm request. Expose new interfaces for this: timer_shutdown_sync() and timer_shutdown(). timer_shutdown_sync() has the same functionality as timer_delete_sync() plus the NULL-ification of the timer function. timer_shutdown() has the same functionality as timer_delete() plus the NULL-ification of the timer function. In both cases the rearming of the timer is prevented by silently discarding rearm attempts due to timer->function being NULL. Co-developed-by: Steven Rostedt Signed-off-by: Steven Rostedt Signed-off-by: Thomas Gleixner Tested-by: Guenter Roeck Reviewed-by: Jacob Keller Reviewed-by: Anna-Maria Behnsen Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org Link: https://lore.kernel.org/r/20221123201625.314230270@linutronix.de (cherry picked from commit f571faf6e443b6011ccb585d57866177af1f643c) CVE-2023-6039 Signed-off-by: Yuxuan Luo --- include/linux/timer.h | 2 ++ kernel/time/timer.c | 66 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/include/linux/timer.h b/include/linux/timer.h index d5aaf3a7adf0..d6c19f4c7395 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -184,6 +184,8 @@ extern void add_timer(struct timer_list *timer); extern int try_to_del_timer_sync(struct timer_list *timer); extern int timer_delete_sync(struct timer_list *timer); extern int timer_delete(struct timer_list *timer); +extern int timer_shutdown_sync(struct timer_list *timer); +extern int timer_shutdown(struct timer_list *timer); /** * del_timer_sync - Delete a pending timer and wait for a running callback diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 9035e336456b..4d6c1beab568 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1319,6 +1319,27 @@ int timer_delete(struct timer_list *timer) } EXPORT_SYMBOL(timer_delete); +/** + * timer_shutdown - Deactivate a timer and prevent rearming + * @timer: The timer to be deactivated + * + * The function does not wait for an eventually running timer callback on a + * different CPU but it prevents rearming of the timer. Any attempt to arm + * @timer after this function returns will be silently ignored. + * + * This function is useful for teardown code and should only be used when + * timer_shutdown_sync() cannot be invoked due to locking or context constraints. + * + * Return: + * * %0 - The timer was not pending + * * %1 - The timer was pending + */ +int timer_shutdown(struct timer_list *timer) +{ + return __timer_delete(timer, true); +} +EXPORT_SYMBOL_GPL(timer_shutdown); + /** * __try_to_del_timer_sync - Internal function: Try to deactivate a timer * @timer: Timer to deactivate @@ -1552,6 +1573,9 @@ static int __timer_delete_sync(struct timer_list *timer, bool shutdown) * lock. If there is the possibility of a concurrent rearm then the return * value of the function is meaningless. * + * If such a guarantee is needed, e.g. for teardown situations then use + * timer_shutdown_sync() instead. + * * Return: * * %0 - The timer was not pending * * %1 - The timer was pending and deactivated @@ -1562,6 +1586,48 @@ int timer_delete_sync(struct timer_list *timer) } EXPORT_SYMBOL(timer_delete_sync); +/** + * timer_shutdown_sync - Shutdown a timer and prevent rearming + * @timer: The timer to be shutdown + * + * When the function returns it is guaranteed that: + * - @timer is not queued + * - The callback function of @timer is not running + * - @timer cannot be enqueued again. Any attempt to rearm + * @timer is silently ignored. + * + * See timer_delete_sync() for synchronization rules. + * + * This function is useful for final teardown of an infrastructure where + * the timer is subject to a circular dependency problem. + * + * A common pattern for this is a timer and a workqueue where the timer can + * schedule work and work can arm the timer. On shutdown the workqueue must + * be destroyed and the timer must be prevented from rearming. Unless the + * code has conditionals like 'if (mything->in_shutdown)' to prevent that + * there is no way to get this correct with timer_delete_sync(). + * + * timer_shutdown_sync() is solving the problem. The correct ordering of + * calls in this case is: + * + * timer_shutdown_sync(&mything->timer); + * workqueue_destroy(&mything->workqueue); + * + * After this 'mything' can be safely freed. + * + * This obviously implies that the timer is not required to be functional + * for the rest of the shutdown operation. + * + * Return: + * * %0 - The timer was not pending + * * %1 - The timer was pending + */ +int timer_shutdown_sync(struct timer_list *timer) +{ + return __timer_delete_sync(timer, true); +} +EXPORT_SYMBOL_GPL(timer_shutdown_sync); + static void call_timer_fn(struct timer_list *timer, void (*fn)(struct timer_list *), unsigned long baseclk) From patchwork Tue Feb 20 19:24:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuxuan Luo X-Patchwork-Id: 1901647 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TfTsG74D7z20Qg for ; Wed, 21 Feb 2024 06:25:54 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1rcVkR-0000xz-Hb; Tue, 20 Feb 2024 19:25:47 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1rcVjX-0008ND-Td for kernel-team@lists.ubuntu.com; Tue, 20 Feb 2024 19:24:52 +0000 Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 2229F3F636 for ; Tue, 20 Feb 2024 19:24:51 +0000 (UTC) Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-1dbe41ad98cso26087915ad.3 for ; Tue, 20 Feb 2024 11:24:51 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708457087; x=1709061887; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=sIvY0d7O4y6iPsU4FXtP0nM3APo6Ao56jaqjS/k8oMA=; b=X2lJzH2w3qLDVWLMxV1HyKswJ0MJSoJRLujwjEKs0pQiSSrj9hhxHCNl0oUx32//wy ZQ4w+/L/rYpitmcjG3bDbTVtuyKLR7ekwROPIg0sXoWTlWZgxvYHgnCVPvUKUYuSu21N V/NusG55W2Bnhyhify3UA3LJicGUhfKtAhl8nngcIC2GiEf8oL3euJEBpKWSRnZ0hG+q l3nCUn+MudF8jm2ZbmRo82kc1vhOXLjEKaJn4XGuoVzSe4b/QNb/bE6pEdqyt7LklsU5 dSBmX5Clustg/Xoh0uWdCm/c5My8jXXzMUjC7e4MpncflBfU7G2t5Bp4GNNu5yFWeI1h WIgw== X-Gm-Message-State: AOJu0YzXNoq/AXDWDwlFaIw0EQl6lRCuRk+Zch3zz3tTwb/GGt/YmeE7 xQgvgCleCNwtKXfabxrAyI18L312caB55UU9zmjopKvU214mKyZfXQYWO+Vo7E7yIfaug68SpN7 B2z34W6u6d4VJBUIH2cWPU083YW7iE9xQdsgv2DKBSwvMf1UGf7yHbAUfoyLetuJ6qI4wnygzq3 cHvUchyQJRHA== X-Received: by 2002:a17:902:efcc:b0:1db:c390:1fdc with SMTP id ja12-20020a170902efcc00b001dbc3901fdcmr9669247plb.1.1708457087380; Tue, 20 Feb 2024 11:24:47 -0800 (PST) X-Google-Smtp-Source: AGHT+IF7caRJgiCX+GwoU3WUuI8Mm+Ww/bVcs5xq8J+FN5I5XCLr2eCsOElGn9+b+/AQ8Ipi7E6Olg== X-Received: by 2002:a17:902:efcc:b0:1db:c390:1fdc with SMTP id ja12-20020a170902efcc00b001dbc3901fdcmr9669237plb.1.1708457087092; Tue, 20 Feb 2024 11:24:47 -0800 (PST) Received: from cache-ubuntu.hsd1.nj.comcast.net ([2001:67c:1562:8007::aac:4795]) by smtp.gmail.com with ESMTPSA id l21-20020a170902e2d500b001d9fcd343edsm6639440plc.208.2024.02.20.11.24.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Feb 2024 11:24:46 -0800 (PST) From: Yuxuan Luo To: kernel-team@lists.ubuntu.com Subject: [SRU][OEM-6.1][PATCH 8/8] net: usb: lan78xx: reorder cleanup operations to avoid UAF bugs Date: Tue, 20 Feb 2024 14:24:21 -0500 Message-Id: <20240220192421.35003-9-yuxuan.luo@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240220192421.35003-1-yuxuan.luo@canonical.com> References: <20240220192421.35003-1-yuxuan.luo@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Duoming Zhou The timer dev->stat_monitor can schedule the delayed work dev->wq and the delayed work dev->wq can also arm the dev->stat_monitor timer. When the device is detaching, the net_device will be deallocated. but the net_device private data could still be dereferenced in delayed work or timer handler. As a result, the UAF bugs will happen. One racy situation is shown below: (Thread 1) | (Thread 2) lan78xx_stat_monitor() | ... | lan78xx_disconnect() lan78xx_defer_kevent() | ... ... | cancel_delayed_work_sync(&dev->wq); schedule_delayed_work() | ... (wait some time) | free_netdev(net); //free net_device lan78xx_delayedwork() | //use net_device private data | dev-> //use | Although we use cancel_delayed_work_sync() to cancel the delayed work in lan78xx_disconnect(), it could still be scheduled in timer handler lan78xx_stat_monitor(). Another racy situation is shown below: (Thread 1) | (Thread 2) lan78xx_delayedwork | mod_timer() | lan78xx_disconnect() | cancel_delayed_work_sync() (wait some time) | if (timer_pending(&dev->stat_monitor)) | del_timer_sync(&dev->stat_monitor); lan78xx_stat_monitor() | ... lan78xx_defer_kevent() | free_netdev(net); //free //use net_device private data| dev-> //use | Although we use del_timer_sync() to delete the timer, the function timer_pending() returns 0 when the timer is activated. As a result, the del_timer_sync() will not be executed and the timer could be re-armed. In order to mitigate this bug, We use timer_shutdown_sync() to shutdown the timer and then use cancel_delayed_work_sync() to cancel the delayed work. As a result, the net_device could be deallocated safely. What's more, the dev->flags is set to EVENT_DEV_DISCONNECT in lan78xx_disconnect(). But it could still be set to EVENT_STAT_UPDATE in lan78xx_stat_monitor(). So this patch put the set_bit() behind timer_shutdown_sync(). Fixes: 77dfff5bb7e2 ("lan78xx: Fix race condition in disconnect handling") Signed-off-by: Duoming Zhou Signed-off-by: David S. Miller (cherry picked from commit 1e7417c188d0a83fb385ba2dbe35fd2563f2b6f3) CVE-2023-6039 Signed-off-by: Yuxuan Luo --- drivers/net/usb/lan78xx.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index c458c030fadf..59cde06aa7f6 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -4224,8 +4224,6 @@ static void lan78xx_disconnect(struct usb_interface *intf) if (!dev) return; - set_bit(EVENT_DEV_DISCONNECT, &dev->flags); - netif_napi_del(&dev->napi); udev = interface_to_usbdev(intf); @@ -4233,6 +4231,8 @@ static void lan78xx_disconnect(struct usb_interface *intf) unregister_netdev(net); + timer_shutdown_sync(&dev->stat_monitor); + set_bit(EVENT_DEV_DISCONNECT, &dev->flags); cancel_delayed_work_sync(&dev->wq); phydev = net->phydev; @@ -4247,9 +4247,6 @@ static void lan78xx_disconnect(struct usb_interface *intf) usb_scuttle_anchored_urbs(&dev->deferred); - if (timer_pending(&dev->stat_monitor)) - del_timer_sync(&dev->stat_monitor); - lan78xx_unbind(dev, intf); lan78xx_free_tx_resources(dev);