get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/1525709/
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 1525709,
    "url": "http://patchwork.ozlabs.org/api/patches/1525709/",
    "web_url": "http://patchwork.ozlabs.org/project/openvswitch/patch/37a5b181b7fd3d4b40ade357ed4c332acbaa1fe1.1631094144.git.grive@u256.net/",
    "project": {
        "id": 47,
        "url": "http://patchwork.ozlabs.org/api/projects/47/",
        "name": "Open vSwitch",
        "link_name": "openvswitch",
        "list_id": "ovs-dev.openvswitch.org",
        "list_email": "ovs-dev@openvswitch.org",
        "web_url": "http://openvswitch.org/",
        "scm_url": "git@github.com:openvswitch/ovs.git",
        "webscm_url": "https://github.com/openvswitch/ovs",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<37a5b181b7fd3d4b40ade357ed4c332acbaa1fe1.1631094144.git.grive@u256.net>",
    "list_archive_url": null,
    "date": "2021-09-08T09:47:25",
    "name": "[ovs-dev,v5,01/27] ovs-thread: Fix barrier use-after-free",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "c30a9b4a996eac581c9bd1de9a964884e398cc34",
    "submitter": {
        "id": 78795,
        "url": "http://patchwork.ozlabs.org/api/people/78795/",
        "name": "Gaëtan Rivet",
        "email": "grive@u256.net"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/openvswitch/patch/37a5b181b7fd3d4b40ade357ed4c332acbaa1fe1.1631094144.git.grive@u256.net/mbox/",
    "series": [
        {
            "id": 261424,
            "url": "http://patchwork.ozlabs.org/api/series/261424/",
            "web_url": "http://patchwork.ozlabs.org/project/openvswitch/list/?series=261424",
            "date": "2021-09-08T09:47:24",
            "name": "dpif-netdev: Parallel offload processing",
            "version": 5,
            "mbox": "http://patchwork.ozlabs.org/series/261424/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/1525709/comments/",
    "check": "success",
    "checks": "http://patchwork.ozlabs.org/api/patches/1525709/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<ovs-dev-bounces@openvswitch.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "ovs-dev@openvswitch.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@bilbo.ozlabs.org",
            "ovs-dev@lists.linuxfoundation.org"
        ],
        "Authentication-Results": [
            "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=u256.net header.i=@u256.net header.a=rsa-sha256\n header.s=fm2 header.b=WjOVNvy0;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=messagingengine.com header.i=@messagingengine.com\n header.a=rsa-sha256 header.s=fm3 header.b=exjgGC+/;\n\tdkim-atps=neutral",
            "ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=140.211.166.138; helo=smtp1.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN>)",
            "smtp3.osuosl.org (amavisd-new);\n dkim=pass (2048-bit key) header.d=u256.net header.b=\"WjOVNvy0\";\n dkim=pass (2048-bit key) header.d=messagingengine.com\n header.b=\"exjgGC+/\""
        ],
        "Received": [
            "from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 4H4HPn665Tz9t54\n\tfor <incoming@patchwork.ozlabs.org>; Wed,  8 Sep 2021 19:48:13 +1000 (AEST)",
            "from localhost (localhost [127.0.0.1])\n\tby smtp1.osuosl.org (Postfix) with ESMTP id 3531F8315C;\n\tWed,  8 Sep 2021 09:48:10 +0000 (UTC)",
            "from smtp1.osuosl.org ([127.0.0.1])\n\tby localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id WN9YaXK-pkR2; Wed,  8 Sep 2021 09:48:08 +0000 (UTC)",
            "from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp1.osuosl.org (Postfix) with ESMTPS id A4D2E82F84;\n\tWed,  8 Sep 2021 09:48:06 +0000 (UTC)",
            "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id E7CBFC0020;\n\tWed,  8 Sep 2021 09:48:04 +0000 (UTC)",
            "from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136])\n by lists.linuxfoundation.org (Postfix) with ESMTP id BCDFCC000D\n for <ovs-dev@openvswitch.org>; Wed,  8 Sep 2021 09:48:03 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n by smtp3.osuosl.org (Postfix) with ESMTP id BA243606ED\n for <ovs-dev@openvswitch.org>; Wed,  8 Sep 2021 09:48:03 +0000 (UTC)",
            "from smtp3.osuosl.org ([127.0.0.1])\n by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n with ESMTP id PLmQKkZPGxTG for <ovs-dev@openvswitch.org>;\n Wed,  8 Sep 2021 09:48:03 +0000 (UTC)",
            "from wout3-smtp.messagingengine.com (wout3-smtp.messagingengine.com\n [64.147.123.19])\n by smtp3.osuosl.org (Postfix) with ESMTPS id 20909606E7\n for <ovs-dev@openvswitch.org>; Wed,  8 Sep 2021 09:48:03 +0000 (UTC)",
            "from compute1.internal (compute1.nyi.internal [10.202.2.41])\n by mailout.west.internal (Postfix) with ESMTP id 878A732009B5;\n Wed,  8 Sep 2021 05:48:02 -0400 (EDT)",
            "from mailfrontend2 ([10.202.2.163])\n by compute1.internal (MEProxy); Wed, 08 Sep 2021 05:48:02 -0400",
            "by mail.messagingengine.com (Postfix) with ESMTPA; Wed,\n 8 Sep 2021 05:48:01 -0400 (EDT)"
        ],
        "X-Virus-Scanned": [
            "amavisd-new at osuosl.org",
            "amavisd-new at osuosl.org"
        ],
        "X-Greylist": "from auto-whitelisted by SQLgrey-1.8.0",
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/relaxed; d=u256.net; h=from\n :to:cc:subject:date:message-id:in-reply-to:references\n :mime-version:content-transfer-encoding; s=fm2; bh=RfJR2N9ZtfI8g\n JnzZTpO+Rw+u0FSWJMgJE2t73bPgu8=; b=WjOVNvy0p/lskTF0vjDRPAjv4PuiR\n XTfV1yq/QlsQ+ZE3L94nyCFZ9AEEqLCCQxi8v5qHkEt32m/CHeEMI7pI0LSvZ0O2\n LtEvaN5cE42Fk39X6c8FfF6G0k4Q2r4PGyMaxNw/+Q6FEHXEFRF4fzw4oWKCgB6M\n Be9VqpZIy5hUtX3A659AVpQ6EOTWijqQ2XTITNV+ehU14Vm2NGbNbexYrV+q0Lqz\n 7XidzTStZVmRqIW1VKVIyi3ExMkwMLqygXgm1pHRhhfAJyBO0vRVg4u5auLnM0Y0\n RPfoml+iQOdJgkF2NeQnVbwAhvWd2wQ/LFbJq9AUnkcIC8e/EJ2/rkoeA==",
            "v=1; a=rsa-sha256; c=relaxed/relaxed; d=\n messagingengine.com; h=cc:content-transfer-encoding:date:from\n :in-reply-to:message-id:mime-version:references:subject:to\n :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=\n fm3; bh=RfJR2N9ZtfI8gJnzZTpO+Rw+u0FSWJMgJE2t73bPgu8=; b=exjgGC+/\n cGNdoQ3U3ydFZfqDDwi2kT+NtObEGX0HdIGo69PBtY6rodEEfts6lZOJTsDWzyg8\n TM+di6HLluUVr5yRl5nEgg/WjVf1Zo67nt33vgNzt8fbmFvWGhINyWlx3enMMROR\n OtBtiZZpaiEAjB4Cw6scqTBxMmcSCa7bb+Fx3Cf5rHs0P6W9sZzqH1byQtXr+QmW\n S5Lx544fwur18yDcYbPPjWtyyWAmsW2gYVpEmkIn1jhyQD4Z6DdVP4qEDPjpHFW8\n LCdGi04POFda9ITNbmVhUAnXJyEZWuwngnpxO+XSlOJHbaOfsZ+NCO46ICk3kEqn\n eISnv0WCSvB0Tw=="
        ],
        "X-ME-Sender": "<xms:0YY4YYcjsh-MVLUsk2cxFw_uXHolgZOe4DVdF20NldvvoSEp_hpvDg>\n <xme:0YY4YaOGLqUAhpB8KDUpf5tM0fRkZx1jznwa2mWfbdL5oALzS7culO-pKmFb20L_G\n kaFDCiBf_TwH0-ByOM>",
        "X-ME-Received": "\n <xmr:0YY4YZgdapHtN8oOtA-Hh6WGz6X7fHbUASVdVstniXPVs8GJeFHt5n2HFnTPpu_VsSepBCeHRNymakzBaWGdugw6Ug>",
        "X-ME-Proxy-Cause": "\n gggruggvucftvghtrhhoucdtuddrgedvtddrudefjedgudekucetufdoteggodetrfdotf\n fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen\n uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne\n cujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefirggvthgr\n nhcutfhivhgvthcuoehgrhhivhgvsehuvdehiedrnhgvtheqnecuggftrfgrthhtvghrnh\n ephefgveffkeetheetfeeifedvheelfeejfeehveduteejhfekuedtkeeiuedvteehnecu\n vehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepghhrihhvvg\n esuhdvheeirdhnvght",
        "X-ME-Proxy": "<xmx:0YY4Yd-VyJ12S_agWMWWnPDrDkD66X3XLQrFm7j17x3UQHcgGGHrzQ>\n <xmx:0YY4YUvu5Sx2PCJMJexKHIq5-MQdEOaAf5f6OjTo276c6wxsNdQlsA>\n <xmx:0YY4YUF0COoRfnde7JeFjUewhCPx6YZ-yoIfB19qYezURC9sRf7JRw>\n <xmx:0oY4Ya1VVH6GaiHBU04CFDm5Gcoo7FG5qLIu-v2kSnQJFbnW1cI_Jg>",
        "From": "Gaetan Rivet <grive@u256.net>",
        "To": "ovs-dev@openvswitch.org",
        "Date": "Wed,  8 Sep 2021 11:47:25 +0200",
        "Message-Id": "\n <37a5b181b7fd3d4b40ade357ed4c332acbaa1fe1.1631094144.git.grive@u256.net>",
        "X-Mailer": "git-send-email 2.31.1",
        "In-Reply-To": "<cover.1631094144.git.grive@u256.net>",
        "References": "<cover.1631094144.git.grive@u256.net>",
        "MIME-Version": "1.0",
        "Cc": "Maxime Coquelin <maxime.coquelin@redhat.com>",
        "Subject": "[ovs-dev] [PATCH v5 01/27] ovs-thread: Fix barrier use-after-free",
        "X-BeenThere": "ovs-dev@openvswitch.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "<ovs-dev.openvswitch.org>",
        "List-Unsubscribe": "<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>",
        "List-Archive": "<http://mail.openvswitch.org/pipermail/ovs-dev/>",
        "List-Post": "<mailto:ovs-dev@openvswitch.org>",
        "List-Help": "<mailto:ovs-dev-request@openvswitch.org?subject=help>",
        "List-Subscribe": "<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=subscribe>",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Errors-To": "ovs-dev-bounces@openvswitch.org",
        "Sender": "\"dev\" <ovs-dev-bounces@openvswitch.org>"
    },
    "content": "When a thread is blocked on a barrier, there is no guarantee\nregarding the moment it will resume, only that it will at some point in\nthe future.\n\nOne thread can resume first then proceed to destroy the barrier while\nanother thread has not yet awoken. When it finally happens, the second\nthread will attempt a seq_read() on the barrier seq, while the first\nthread have already destroyed it, triggering a use-after-free.\n\nIntroduce an additional indirection layer within the barrier.\nA internal barrier implementation holds all the necessary elements\nfor a thread to safely block and destroy. Whenever a barrier is\ndestroyed, the internal implementation is left available to still\nblocking threads if necessary. A reference counter is used to track\nthreads still using the implementation.\n\nNote that current uses of ovs-barrier are not affected: RCU and\nrevalidators will not destroy their barrier immediately after blocking\non it.\n\nFixes: d8043da7182a (\"ovs-thread: Implement OVS specific barrier.\")\nSigned-off-by: Gaetan Rivet <grive@u256.net>\nReviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>\n---\n lib/ovs-thread.c | 61 +++++++++++++++++++++++++++++++++++++++---------\n lib/ovs-thread.h |  6 ++---\n 2 files changed, 53 insertions(+), 14 deletions(-)",
    "diff": "diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c\nindex b686e4548..805cba622 100644\n--- a/lib/ovs-thread.c\n+++ b/lib/ovs-thread.c\n@@ -299,21 +299,53 @@ ovs_spin_init(const struct ovs_spin *spin)\n }\n #endif\n \n+struct ovs_barrier_impl {\n+    uint32_t size;            /* Number of threads to wait. */\n+    atomic_count count;       /* Number of threads already hit the barrier. */\n+    struct seq *seq;\n+    struct ovs_refcount refcnt;\n+};\n+\n+static void\n+ovs_barrier_impl_ref(struct ovs_barrier_impl *impl)\n+{\n+    ovs_refcount_ref(&impl->refcnt);\n+}\n+\n+static void\n+ovs_barrier_impl_unref(struct ovs_barrier_impl *impl)\n+{\n+    if (ovs_refcount_unref(&impl->refcnt) == 1) {\n+        seq_destroy(impl->seq);\n+        free(impl);\n+    }\n+}\n+\n /* Initializes the 'barrier'.  'size' is the number of threads\n  * expected to hit the barrier. */\n void\n ovs_barrier_init(struct ovs_barrier *barrier, uint32_t size)\n {\n-    barrier->size = size;\n-    atomic_count_init(&barrier->count, 0);\n-    barrier->seq = seq_create();\n+    struct ovs_barrier_impl *impl;\n+\n+    impl = xmalloc(sizeof *impl);\n+    impl->size = size;\n+    atomic_count_init(&impl->count, 0);\n+    impl->seq = seq_create();\n+    ovs_refcount_init(&impl->refcnt);\n+\n+    ovsrcu_set(&barrier->impl, impl);\n }\n \n /* Destroys the 'barrier'. */\n void\n ovs_barrier_destroy(struct ovs_barrier *barrier)\n {\n-    seq_destroy(barrier->seq);\n+    struct ovs_barrier_impl *impl;\n+\n+    impl = ovsrcu_get(struct ovs_barrier_impl *, &barrier->impl);\n+    ovsrcu_set(&barrier->impl, NULL);\n+    ovs_barrier_impl_unref(impl);\n }\n \n /* Makes the calling thread block on the 'barrier' until all\n@@ -325,23 +357,30 @@ ovs_barrier_destroy(struct ovs_barrier *barrier)\n void\n ovs_barrier_block(struct ovs_barrier *barrier)\n {\n-    uint64_t seq = seq_read(barrier->seq);\n+    struct ovs_barrier_impl *impl;\n     uint32_t orig;\n+    uint64_t seq;\n \n-    orig = atomic_count_inc(&barrier->count);\n-    if (orig + 1 == barrier->size) {\n-        atomic_count_set(&barrier->count, 0);\n+    impl = ovsrcu_get(struct ovs_barrier_impl *, &barrier->impl);\n+    ovs_barrier_impl_ref(impl);\n+\n+    seq = seq_read(impl->seq);\n+    orig = atomic_count_inc(&impl->count);\n+    if (orig + 1 == impl->size) {\n+        atomic_count_set(&impl->count, 0);\n         /* seq_change() serves as a release barrier against the other threads,\n          * so the zeroed count is visible to them as they continue. */\n-        seq_change(barrier->seq);\n+        seq_change(impl->seq);\n     } else {\n         /* To prevent thread from waking up by other event,\n          * keeps waiting for the change of 'barrier->seq'. */\n-        while (seq == seq_read(barrier->seq)) {\n-            seq_wait(barrier->seq, seq);\n+        while (seq == seq_read(impl->seq)) {\n+            seq_wait(impl->seq, seq);\n             poll_block();\n         }\n     }\n+\n+    ovs_barrier_impl_unref(impl);\n }\n \f\n DEFINE_EXTERN_PER_THREAD_DATA(ovsthread_id, OVSTHREAD_ID_UNSET);\ndiff --git a/lib/ovs-thread.h b/lib/ovs-thread.h\nindex 7ee98bd4e..3b444ccdc 100644\n--- a/lib/ovs-thread.h\n+++ b/lib/ovs-thread.h\n@@ -21,16 +21,16 @@\n #include <stddef.h>\n #include <sys/types.h>\n #include \"ovs-atomic.h\"\n+#include \"ovs-rcu.h\"\n #include \"openvswitch/thread.h\"\n #include \"util.h\"\n \n struct seq;\n \n /* Poll-block()-able barrier similar to pthread_barrier_t. */\n+struct ovs_barrier_impl;\n struct ovs_barrier {\n-    uint32_t size;            /* Number of threads to wait. */\n-    atomic_count count;       /* Number of threads already hit the barrier. */\n-    struct seq *seq;\n+    OVSRCU_TYPE(struct ovs_barrier_impl *) impl;\n };\n \n /* Wrappers for pthread_mutexattr_*() that abort the process on any error. */\n",
    "prefixes": [
        "ovs-dev",
        "v5",
        "01/27"
    ]
}