From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx1.secunet.com (mx1.secunet.com [62.96.220.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6C90B3EDE48 for ; Wed, 10 Jun 2026 14:08:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.96.220.36 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781100499; cv=none; b=GP8FQi4BTgZfokbT02cZ0P3JlSXaOCCz/JhYgV9hhho/9idtWrPQ1PB5gpYkiFLSUzhLw1NoXkKgemBgPUIUKe45pUjqNXp0lYObZ4jcP4YdoLqHJp3V2SPEAgYSSv/jNI4flSJDQex9YpCP+5ADi2f4vX0RjZJKCn0vMZJUAp8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781100499; c=relaxed/simple; bh=SprnDYzFdEoZvE5U46+dSuGuGxBqXlRpvvJrLWwHQlk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=bmlL4YKH5DTxAUq2pa+8OfWCRjkrF5N9BM2uviGaBH/WqQ3fGgA9tvI+hsrqbE/ab8HaSE3b25ar8DsyI59TmnlhCdsJNkpkANKRwD0vzR6zW4yoFmvlj0ERFKuh3GfvbBOqZQrAXkUKtTdJQHcMRXXSBS++cTtL506Fgq31UjQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=secunet.com; spf=pass smtp.mailfrom=secunet.com; dkim=pass (2048-bit key) header.d=secunet.com header.i=@secunet.com header.b=PybWfLv1; arc=none smtp.client-ip=62.96.220.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=secunet.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=secunet.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=secunet.com header.i=@secunet.com header.b="PybWfLv1" Received: from localhost (localhost [127.0.0.1]) by mx1.secunet.com (Postfix) with ESMTP id 5CFEE20764; Wed, 10 Jun 2026 16:08:10 +0200 (CEST) X-Virus-Scanned: by secunet Received: from mx1.secunet.com ([127.0.0.1]) by localhost (mx1.secunet.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id veUIgNgZZ9P3; Wed, 10 Jun 2026 16:08:09 +0200 (CEST) Received: from EXCH-01.secunet.de (rl1.secunet.de [10.32.0.231]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.secunet.com (Postfix) with ESMTPS id B2ABB20758; Wed, 10 Jun 2026 16:08:09 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.secunet.com B2ABB20758 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=secunet.com; s=202301; t=1781100489; bh=BxjVpY+HQNhdLt1UlKyAEhcHoMpuOb5+M1ZGj2E2yRw=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=PybWfLv1sLgiAxsCHbW2PIWZ1eLwi6KPmvTrks8NLxCF45MUiVoPhZCRZ0O/uTNT1 7Pj8f7V8wk93atCmlnl5HGSIOGb89MU3HwMq7RRY8rVy/RozR+5t7NAUpXjKoNtyZy 4vdrbMTi73bdSDTqYAxo4h0BruSN4yQFFFQYDiqq9OjqhojUTx4P2DrpMrjSQG1sSv z60wbR+3F5QhUbRtLUf0PisGyFbKQTC6OdqfW9RiwhHiz+J5dRWwjplKwcGRYhFklf CK8rYqsNZ4LNH+DdAQY+t72KgHkUHPqWyG5GvGQXHnnKdLiv3QGsHC56FlYCHnb2A1 zEmWa3rrKCvGQ== Received: from secunet.com (10.182.7.193) by EXCH-01.secunet.de (10.32.0.171) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.37; Wed, 10 Jun 2026 16:08:09 +0200 Received: (nullmailer pid 2563203 invoked by uid 1000); Wed, 10 Jun 2026 14:08:07 -0000 From: Steffen Klassert To: David Miller , Jakub Kicinski CC: Herbert Xu , Steffen Klassert , Subject: [PATCH 4/6] xfrm: iptfs: fix ABBA deadlock in iptfs_destroy_state() Date: Wed, 10 Jun 2026 16:07:43 +0200 Message-ID: <20260610140800.2562818-5-steffen.klassert@secunet.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260610140800.2562818-1-steffen.klassert@secunet.com> References: <20260610140800.2562818-1-steffen.klassert@secunet.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: EXCH-03.secunet.de (10.32.0.183) To EXCH-01.secunet.de (10.32.0.171) From: Tristan Madani iptfs_destroy_state() calls hrtimer_cancel() while holding a spinlock that the timer callback also acquires, leading to an ABBA deadlock on SMP systems. For the output timer (iptfs_timer): - iptfs_destroy_state() holds x->lock, calls hrtimer_cancel() - iptfs_delay_timer() callback takes x->lock For the drop timer (drop_timer): - iptfs_destroy_state() holds drop_lock, calls hrtimer_cancel() - iptfs_drop_timer() callback takes drop_lock Both timers use HRTIMER_MODE_REL_SOFT, so their callbacks run in softirq context. When hrtimer_cancel() is called for a soft timer that is currently executing on another CPU, hrtimer_cancel_wait_running() spins on softirq_expiry_lock -- the same lock held by the softirq running the callback. If the callback is blocked waiting for the spinlock held by the caller of hrtimer_cancel(), a circular dependency forms: CPU 0: holds lock_A -> waits for softirq_expiry_lock CPU 1: holds softirq_expiry_lock -> waits for lock_A Fix by calling hrtimer_cancel() before acquiring the respective locks. hrtimer_cancel() is safe to call without holding any lock and will wait for any in-progress callback to complete. For the output timer, the lock is still acquired afterwards to drain the packet queue. For the drop timer, the lock/unlock pair is removed entirely since it only existed to serialize with the timer callback, which hrtimer_cancel() already guarantees. Found by source code audit. Fixes: 4b3faf610cc6 ("xfrm: iptfs: add new iptfs xfrm mode impl") Cc: Christian Hopps Cc: Steffen Klassert Cc: stable@vger.kernel.org Signed-off-by: Tristan Madani Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_iptfs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/xfrm/xfrm_iptfs.c b/net/xfrm/xfrm_iptfs.c index aea63a000d1d..ad810d1f97c0 100644 --- a/net/xfrm/xfrm_iptfs.c +++ b/net/xfrm/xfrm_iptfs.c @@ -2730,8 +2730,9 @@ static void iptfs_destroy_state(struct xfrm_state *x) if (!xtfs) return; - spin_lock_bh(&xtfs->x->lock); hrtimer_cancel(&xtfs->iptfs_timer); + + spin_lock_bh(&xtfs->x->lock); __skb_queue_head_init(&list); skb_queue_splice_init(&xtfs->queue, &list); spin_unlock_bh(&xtfs->x->lock); @@ -2739,9 +2740,7 @@ static void iptfs_destroy_state(struct xfrm_state *x) while ((skb = __skb_dequeue(&list))) kfree_skb(skb); - spin_lock_bh(&xtfs->drop_lock); hrtimer_cancel(&xtfs->drop_timer); - spin_unlock_bh(&xtfs->drop_lock); if (xtfs->ra_newskb) kfree_skb(xtfs->ra_newskb); -- 2.43.0