Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2219406/?format=api
{ "id": 2219406, "url": "http://patchwork.ozlabs.org/api/patches/2219406/?format=api", "web_url": "http://patchwork.ozlabs.org/project/ubuntu-kernel/patch/20260402230724.1279847-3-tim.whisonant@canonical.com/", "project": { "id": 15, "url": "http://patchwork.ozlabs.org/api/projects/15/?format=api", "name": "Ubuntu Kernel", "link_name": "ubuntu-kernel", "list_id": "kernel-team.lists.ubuntu.com", "list_email": "kernel-team@lists.ubuntu.com", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260402230724.1279847-3-tim.whisonant@canonical.com>", "list_archive_url": null, "date": "2026-04-02T23:07:20", "name": "[SRU,Q,1/1] af_unix: Give up GC if MSG_PEEK intervened.", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "b0a43432fd48db21a9e2575678777efaf3d96d36", "submitter": { "id": 89903, "url": "http://patchwork.ozlabs.org/api/people/89903/?format=api", "name": "Tim Whisonant", "email": "tim.whisonant@canonical.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/ubuntu-kernel/patch/20260402230724.1279847-3-tim.whisonant@canonical.com/mbox/", "series": [ { "id": 498561, "url": "http://patchwork.ozlabs.org/api/series/498561/?format=api", "web_url": "http://patchwork.ozlabs.org/project/ubuntu-kernel/list/?series=498561", "date": "2026-04-02T23:07:18", "name": "CVE-2026-23394", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/498561/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2219406/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2219406/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<kernel-team-bounces@lists.ubuntu.com>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (4096-bit key;\n unprotected) header.d=canonical.com header.i=@canonical.com\n header.a=rsa-sha256 header.s=20251003 header.b=T82D/N0a;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com\n (client-ip=185.125.189.65; helo=lists.ubuntu.com;\n envelope-from=kernel-team-bounces@lists.ubuntu.com;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fmyDx3cppz1yFT\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 03 Apr 2026 10:07:45 +1100 (AEDT)", "from localhost ([127.0.0.1] helo=lists.ubuntu.com)\n\tby lists.ubuntu.com with esmtp (Exim 4.86_2)\n\t(envelope-from <kernel-team-bounces@lists.ubuntu.com>)\n\tid 1w8R8U-0004Hz-LZ; Thu, 02 Apr 2026 23:07:38 +0000", "from smtp-relay-internal-1.internal ([10.131.114.114]\n helo=smtp-relay-internal-1.canonical.com)\n by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.86_2) (envelope-from <tim.whisonant@canonical.com>)\n id 1w8R8T-0004Fk-C2\n for kernel-team@lists.ubuntu.com; Thu, 02 Apr 2026 23:07:37 +0000", "from mail-ot1-f72.google.com (mail-ot1-f72.google.com\n [209.85.210.72])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 2F1023F615\n for <kernel-team@lists.ubuntu.com>; Thu, 2 Apr 2026 23:07:37 +0000 (UTC)", "by mail-ot1-f72.google.com with SMTP id\n 46e09a7af769-7d7cfbcb7c0so3170167a34.0\n for <kernel-team@lists.ubuntu.com>; Thu, 02 Apr 2026 16:07:37 -0700 (PDT)", "from localhost (104-6-108-11.lightspeed.frokca.sbcglobal.net.\n [104.6.108.11]) by smtp.gmail.com with ESMTPSA id\n 46e09a7af769-7dba72fcb47sm3184703a34.15.2026.04.02.16.07.34\n for <kernel-team@lists.ubuntu.com>\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Thu, 02 Apr 2026 16:07:34 -0700 (PDT)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com;\n s=20251003; t=1775171257;\n bh=A5cHkL9D/727JK4RJnYu8hpXyczPlIkLR+ndO9ghoFc=;\n h=From:To:Subject:Date:Message-ID:In-Reply-To:References:\n MIME-Version;\n b=T82D/N0aFK/qE/Fv+TOdgTgae3MFtVGS5qjYCsYKiAa/iRgpkurIjfz/KFDzScV1R\n Kd1AllyiSZeXKzbHDY8mkecdQFu1W3vZ2coe1mr5+CanlxR9liIpfHrrv7e0k0iB9w\n 9QlacoXajAC7TdudOF6+6rxDPtd6R7d4zinMhLSNarqGBM4HRFrTWEHrLciMibFRpQ\n JhNp95MbWJy37WueXR2nqChN7YTG7SELHg11njSdE3Uk77XGV04rJeof+3NFmmXAOO\n vJWYUN5krymCkyb2uk0S/njhYvE5dCiXSscG8wekrYyYAUfs9ORdMPiDPJuck+e0xb\n 6XUmdVWe0btvjnGx6fhEaCPww3sCIuevjKxeYniccFG/zfQqZB/DSi5orsW6AgoQcg\n NJp3U7MoITSnHWHlem2aISAPupE+3sQ8X+WUoIiXwA6nZOXy/WWllttNw9XQoQ7842\n uo20fNZaMpTBQooibRGsNZLlN9GcRXfJsKW6+73SYuwnAlCLZHLikpQiHiNWw4A6xb\n NHSMKwU0k75HkoKvCWQ2AcZ09W8TMqDBse92PMT900TnZuQrJr0CosP/IFuBh3+v3P\n Xk+G3ARPqhMV1nCzafNvt91FiG9RwFz2tV02cvrkj7WOVKlum/yVYPdIHKCvIuklzN\n o03/VVWkhvSqEb0ezSDv0cO0=", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1775171255; x=1775776055;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to\n :cc:subject:date:message-id:reply-to;\n bh=A5cHkL9D/727JK4RJnYu8hpXyczPlIkLR+ndO9ghoFc=;\n b=F5rXrd+MwkmHPWcZVX1NZqRnPaemuPLGF9CpeEzE3ZtNtxtuEgqay02Fd2zuj90wb5\n I8AjwpuJzUdys0R5PuIjexZMr5SWTZ64R5L5ZimLzMnXAZ+Ek/4xwAXv6dfso45lKxA9\n 00PF6ZLxHFlsmn+quc6F0A36yR0nt9OVV/yBu06YI+wLa4MWjv/HJcUL4C8GOz0/pdtD\n XJV7qGIx/dDyjzkJ18LBE/9WbpIFQujHfNgmDi5tVI2mPKsLsLDnYYVzVn6JUwr+cwwc\n A4OnFFgL9alqq1vqYbObPu9Zwb8QMqUQSdUTLviuczsJfaJ/nwuzXt1zNG09gXZVO9fL\n qyVA==", "X-Gm-Message-State": "AOJu0YzcFPL3XnMYDbXlHXU+hzMz5pUIsXwR0Sojt9+JUlNcptPu6srL\n oSwz+esuDkRNdv/pYC0cnZNYawRQk/7S5AvNGcsflVOI+dsBX0BGSH6Jupzs40R4T9lvGUvuwqZ\n ma3Qymxo3RSRXmd/xOw5vgPABPPnqJtUI7ouw+axH+Ay948UMKu9FKEb6t4q3OiG1eVNyux0WMC\n /PF8PFnqbuBKCYlA==", "X-Gm-Gg": "ATEYQzznMaaRYPhU9+f1b7c6NBpb90PGkKKMxSxjWzFXMhrx4DbiS6pTiufON0GShmM\n 1U23xvargI9xfprUNdxtWdHxO/6Ffg8A5SBYVjPRJEV4VdQwuGYjsL3In7VgwOick09Kpd29kyZ\n RMK5AOqB5GqAeggfXYMM0nA4d+POynGMuFVS804eDntNFBHO0LaNOylsSxtwD2q4jsSBNZzsmZk\n 32oUyPB6fdXiVohAJtsK3AEsDhyqmF5Td/CMwXl0DRFibhGB/0TAUhtxwLCC0axfpjt6PisDLGR\n vfyh8rJsDgDJwYk+PtkYZYjCs+rSUEb5yDXv0UUQkiBB2qS1Vt/XFgrlUQQgcwT1mZWvXJRWo8y\n eVrCzsFEOOryCxFBEl58XcuxCEGPQ7egN54+iIyVZPAr/2fo9B4WkK7kD6LHefvC14X0sLzc55B\n yVxw==", "X-Received": [ "by 2002:a05:6830:6f89:b0:7d7:4639:43ee with SMTP id\n 46e09a7af769-7dbb732d54emr707644a34.3.1775171255471;\n Thu, 02 Apr 2026 16:07:35 -0700 (PDT)", "by 2002:a05:6830:6f89:b0:7d7:4639:43ee with SMTP id\n 46e09a7af769-7dbb732d54emr707627a34.3.1775171255001;\n Thu, 02 Apr 2026 16:07:35 -0700 (PDT)" ], "From": "Tim Whisonant <tim.whisonant@canonical.com>", "To": "kernel-team@lists.ubuntu.com", "Subject": "[SRU][Q][PATCH 1/1] af_unix: Give up GC if MSG_PEEK intervened.", "Date": "Thu, 2 Apr 2026 16:07:20 -0700", "Message-ID": "<20260402230724.1279847-3-tim.whisonant@canonical.com>", "X-Mailer": "git-send-email 2.43.0", "In-Reply-To": "<20260402230724.1279847-1-tim.whisonant@canonical.com>", "References": "<20260402230724.1279847-1-tim.whisonant@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 <kernel-team.lists.ubuntu.com>", "List-Unsubscribe": "<https://lists.ubuntu.com/mailman/options/kernel-team>,\n <mailto:kernel-team-request@lists.ubuntu.com?subject=unsubscribe>", "List-Archive": "<https://lists.ubuntu.com/archives/kernel-team>", "List-Post": "<mailto:kernel-team@lists.ubuntu.com>", "List-Help": "<mailto:kernel-team-request@lists.ubuntu.com?subject=help>", "List-Subscribe": "<https://lists.ubuntu.com/mailman/listinfo/kernel-team>,\n <mailto:kernel-team-request@lists.ubuntu.com?subject=subscribe>", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "base64", "Errors-To": "kernel-team-bounces@lists.ubuntu.com", "Sender": "\"kernel-team\" <kernel-team-bounces@lists.ubuntu.com>" }, "content": "From: Kuniyuki Iwashima <kuniyu@google.com>\n\nIgor Ushakov reported that GC purged the receive queue of\nan alive socket due to a race with MSG_PEEK with a nice repro.\n\nThis is the exact same issue previously fixed by commit\ncbcf01128d0a (\"af_unix: fix garbage collect vs MSG_PEEK\").\n\nAfter GC was replaced with the current algorithm, the cited\ncommit removed the locking dance in unix_peek_fds() and\nreintroduced the same issue.\n\nThe problem is that MSG_PEEK bumps a file refcount without\ninteracting with GC.\n\nConsider an SCC containing sk-A and sk-B, where sk-A is\nclose()d but can be recv()ed via sk-B.\n\nThe bad thing happens if sk-A is recv()ed with MSG_PEEK from\nsk-B and sk-B is close()d while GC is checking unix_vertex_dead()\nfor sk-A and sk-B.\n\n GC thread User thread\n --------- -----------\n unix_vertex_dead(sk-A)\n -> true <------.\n \\\n `------ recv(sk-B, MSG_PEEK)\n invalidate !! -> sk-A's file refcount : 1 -> 2\n\n close(sk-B)\n -> sk-B's file refcount : 2 -> 1\n unix_vertex_dead(sk-B)\n -> true\n\nInitially, sk-A's file refcount is 1 by the inflight fd in sk-B\nrecvq. GC thinks sk-A is dead because the file refcount is the\nsame as the number of its inflight fds.\n\nHowever, sk-A's file refcount is bumped silently by MSG_PEEK,\nwhich invalidates the previous evaluation.\n\nAt this moment, sk-B's file refcount is 2; one by the open fd,\nand one by the inflight fd in sk-A. The subsequent close()\nreleases one refcount by the former.\n\nFinally, GC incorrectly concludes that both sk-A and sk-B are dead.\n\nOne option is to restore the locking dance in unix_peek_fds(),\nbut we can resolve this more elegantly thanks to the new algorithm.\n\nThe point is that the issue does not occur without the subsequent\nclose() and we actually do not need to synchronise MSG_PEEK with\nthe dead SCC detection.\n\nWhen the issue occurs, close() and GC touch the same file refcount.\nIf GC sees the refcount being decremented by close(), it can just\ngive up garbage-collecting the SCC.\n\nTherefore, we only need to signal the race during MSG_PEEK with\na proper memory barrier to make it visible to the GC.\n\nLet's use seqcount_t to notify GC when MSG_PEEK occurs and let\nit defer the SCC to the next run.\n\nThis way no locking is needed on the MSG_PEEK side, and we can\navoid imposing a penalty on every MSG_PEEK unnecessarily.\n\nNote that we can retry within unix_scc_dead() if MSG_PEEK is\ndetected, but we do not do so to avoid hung task splat from\nabusive MSG_PEEK calls.\n\nFixes: 118f457da9ed (\"af_unix: Remove lock dance in unix_peek_fds().\")\nReported-by: Igor Ushakov <sysroot314@gmail.com>\nSigned-off-by: Kuniyuki Iwashima <kuniyu@google.com>\nLink: https://patch.msgid.link/20260311054043.1231316-1-kuniyu@google.com\nSigned-off-by: Jakub Kicinski <kuba@kernel.org>\n(backported from commit e5b31d988a41549037b8d8721a3c3cae893d8670)\n[tswhison: context adjustments due to missing commits\nda8fc7a39be (\"af_unix: Don't trigger GC from close() if unnecessary.\")\n24fa77dad25 (\"af_unix: Consolidate unix_schedule_gc() and wait_for_unix_gc().\")\n58b47c71371 (\"af_unix: Count cyclic SCC.\")]\nCVE-2026-23394\nSigned-off-by: Tim Whisonant <tim.whisonant@canonical.com>\n---\n net/unix/af_unix.c | 2 ++\n net/unix/af_unix.h | 1 +\n net/unix/garbage.c | 79 ++++++++++++++++++++++++++++++----------------\n 3 files changed, 54 insertions(+), 28 deletions(-)", "diff": "diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c\nindex 0f288a80e0acd..0c3166ff2bd76 100644\n--- a/net/unix/af_unix.c\n+++ b/net/unix/af_unix.c\n@@ -1984,6 +1984,8 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)\n static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb)\n {\n \tscm->fp = scm_fp_dup(UNIXCB(skb).fp);\n+\n+\tunix_peek_fpl(scm->fp);\n }\n \n static void unix_destruct_scm(struct sk_buff *skb)\ndiff --git a/net/unix/af_unix.h b/net/unix/af_unix.h\nindex 59db179df9bb5..6b96c1007aecd 100644\n--- a/net/unix/af_unix.h\n+++ b/net/unix/af_unix.h\n@@ -30,6 +30,7 @@ void unix_del_edges(struct scm_fp_list *fpl);\n void unix_update_edges(struct unix_sock *receiver);\n int unix_prepare_fpl(struct scm_fp_list *fpl);\n void unix_destroy_fpl(struct scm_fp_list *fpl);\n+void unix_peek_fpl(struct scm_fp_list *fpl);\n void unix_gc(void);\n void wait_for_unix_gc(struct scm_fp_list *fpl);\n \ndiff --git a/net/unix/garbage.c b/net/unix/garbage.c\nindex 358fcaba9a732..a806dcb4a4b80 100644\n--- a/net/unix/garbage.c\n+++ b/net/unix/garbage.c\n@@ -315,6 +315,25 @@ void unix_destroy_fpl(struct scm_fp_list *fpl)\n \tunix_free_vertices(fpl);\n }\n \n+static bool gc_in_progress;\n+static seqcount_t unix_peek_seq = SEQCNT_ZERO(unix_peek_seq);\n+\n+void unix_peek_fpl(struct scm_fp_list *fpl)\n+{\n+\tstatic DEFINE_SPINLOCK(unix_peek_lock);\n+\n+\tif (!fpl || !fpl->count_unix)\n+\t\treturn;\n+\n+\tif (!READ_ONCE(gc_in_progress))\n+\t\treturn;\n+\n+\t/* Invalidate the final refcnt check in unix_vertex_dead(). */\n+\tspin_lock(&unix_peek_lock);\n+\traw_write_seqcount_barrier(&unix_peek_seq);\n+\tspin_unlock(&unix_peek_lock);\n+}\n+\n static bool unix_vertex_dead(struct unix_vertex *vertex)\n {\n \tstruct unix_edge *edge;\n@@ -348,6 +367,36 @@ static bool unix_vertex_dead(struct unix_vertex *vertex)\n \treturn true;\n }\n \n+static LIST_HEAD(unix_visited_vertices);\n+static unsigned long unix_vertex_grouped_index = UNIX_VERTEX_INDEX_MARK2;\n+\n+static bool unix_scc_dead(struct list_head *scc, bool fast)\n+{\n+\tstruct unix_vertex *vertex;\n+\tbool scc_dead = true;\n+\tunsigned int seq;\n+\n+\tseq = read_seqcount_begin(&unix_peek_seq);\n+\n+\tlist_for_each_entry_reverse(vertex, scc, scc_entry) {\n+\t\t/* Don't restart DFS from this vertex. */\n+\t\tlist_move_tail(&vertex->entry, &unix_visited_vertices);\n+\n+\t\t/* Mark vertex as off-stack for __unix_walk_scc(). */\n+\t\tif (!fast)\n+\t\t\tvertex->index = unix_vertex_grouped_index;\n+\n+\t\tif (scc_dead)\n+\t\t\tscc_dead = unix_vertex_dead(vertex);\n+\t}\n+\n+\t/* If MSG_PEEK intervened, defer this SCC to the next round. */\n+\tif (read_seqcount_retry(&unix_peek_seq, seq))\n+\t\treturn false;\n+\n+\treturn scc_dead;\n+}\n+\n static void unix_collect_skb(struct list_head *scc, struct sk_buff_head *hitlist)\n {\n \tstruct unix_vertex *vertex;\n@@ -401,9 +450,6 @@ static bool unix_scc_cyclic(struct list_head *scc)\n \treturn false;\n }\n \n-static LIST_HEAD(unix_visited_vertices);\n-static unsigned long unix_vertex_grouped_index = UNIX_VERTEX_INDEX_MARK2;\n-\n static void __unix_walk_scc(struct unix_vertex *vertex, unsigned long *last_index,\n \t\t\t struct sk_buff_head *hitlist)\n {\n@@ -469,9 +515,7 @@ static void __unix_walk_scc(struct unix_vertex *vertex, unsigned long *last_inde\n \t}\n \n \tif (vertex->index == vertex->scc_index) {\n-\t\tstruct unix_vertex *v;\n \t\tstruct list_head scc;\n-\t\tbool scc_dead = true;\n \n \t\t/* SCC finalised.\n \t\t *\n@@ -480,18 +524,7 @@ static void __unix_walk_scc(struct unix_vertex *vertex, unsigned long *last_inde\n \t\t */\n \t\t__list_cut_position(&scc, &vertex_stack, &vertex->scc_entry);\n \n-\t\tlist_for_each_entry_reverse(v, &scc, scc_entry) {\n-\t\t\t/* Don't restart DFS from this vertex in unix_walk_scc(). */\n-\t\t\tlist_move_tail(&v->entry, &unix_visited_vertices);\n-\n-\t\t\t/* Mark vertex as off-stack. */\n-\t\t\tv->index = unix_vertex_grouped_index;\n-\n-\t\t\tif (scc_dead)\n-\t\t\t\tscc_dead = unix_vertex_dead(v);\n-\t\t}\n-\n-\t\tif (scc_dead) {\n+\t\tif (unix_scc_dead(&scc, false)) {\n \t\t\tunix_collect_skb(&scc, hitlist);\n \t\t} else {\n \t\t\tif (unix_vertex_max_scc_index < vertex->scc_index)\n@@ -539,19 +572,11 @@ static void unix_walk_scc_fast(struct sk_buff_head *hitlist)\n \twhile (!list_empty(&unix_unvisited_vertices)) {\n \t\tstruct unix_vertex *vertex;\n \t\tstruct list_head scc;\n-\t\tbool scc_dead = true;\n \n \t\tvertex = list_first_entry(&unix_unvisited_vertices, typeof(*vertex), entry);\n \t\tlist_add(&scc, &vertex->scc_entry);\n \n-\t\tlist_for_each_entry_reverse(vertex, &scc, scc_entry) {\n-\t\t\tlist_move_tail(&vertex->entry, &unix_visited_vertices);\n-\n-\t\t\tif (scc_dead)\n-\t\t\t\tscc_dead = unix_vertex_dead(vertex);\n-\t\t}\n-\n-\t\tif (scc_dead)\n+\t\tif (unix_scc_dead(&scc, true))\n \t\t\tunix_collect_skb(&scc, hitlist);\n \t\telse if (!unix_graph_maybe_cyclic)\n \t\t\tunix_graph_maybe_cyclic = unix_scc_cyclic(&scc);\n@@ -562,8 +587,6 @@ static void unix_walk_scc_fast(struct sk_buff_head *hitlist)\n \tlist_replace_init(&unix_visited_vertices, &unix_unvisited_vertices);\n }\n \n-static bool gc_in_progress;\n-\n static void __unix_gc(struct work_struct *work)\n {\n \tstruct sk_buff_head hitlist;\n", "prefixes": [ "SRU", "Q", "1/1" ] }