get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.2/patches/2234951/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2234951,
    "url": "http://patchwork.ozlabs.org/api/1.2/patches/2234951/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/patch/20260508105448.31799-10-tzungbi@kernel.org/",
    "project": {
        "id": 42,
        "url": "http://patchwork.ozlabs.org/api/1.2/projects/42/?format=api",
        "name": "Linux GPIO development",
        "link_name": "linux-gpio",
        "list_id": "linux-gpio.vger.kernel.org",
        "list_email": "linux-gpio@vger.kernel.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260508105448.31799-10-tzungbi@kernel.org>",
    "list_archive_url": null,
    "date": "2026-05-08T10:54:48",
    "name": "[v10,9/9] platform/chrome: cros_ec_chardev: Consume cros_ec_device via revocable",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "8aec34050f54275a1129e8db89a739a4daf1df4b",
    "submitter": {
        "id": 83557,
        "url": "http://patchwork.ozlabs.org/api/1.2/people/83557/?format=api",
        "name": "Tzung-Bi Shih",
        "email": "tzungbi@kernel.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-gpio/patch/20260508105448.31799-10-tzungbi@kernel.org/mbox/",
    "series": [
        {
            "id": 503368,
            "url": "http://patchwork.ozlabs.org/api/1.2/series/503368/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/list/?series=503368",
            "date": "2026-05-08T10:54:39",
            "name": "drivers/base: Introduce revocable",
            "version": 10,
            "mbox": "http://patchwork.ozlabs.org/series/503368/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2234951/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2234951/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "\n <linux-gpio+bounces-36453-incoming=patchwork.ozlabs.org@vger.kernel.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "linux-gpio@vger.kernel.org"
        ],
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=hiZkIDNu;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=172.234.253.10; helo=sea.lore.kernel.org;\n envelope-from=linux-gpio+bounces-36453-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)",
            "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=\"hiZkIDNu\"",
            "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201"
        ],
        "Received": [
            "from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4gBmRY6Gpgz1yJq\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 08 May 2026 21:02:33 +1000 (AEST)",
            "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 2D57E30C0A01\n\tfor <incoming@patchwork.ozlabs.org>; Fri,  8 May 2026 10:56:13 +0000 (UTC)",
            "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 1D8F63446AB;\n\tFri,  8 May 2026 10:55:56 +0000 (UTC)",
            "from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org\n [10.30.226.201])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id CCDDC345CAE;\n\tFri,  8 May 2026 10:55:55 +0000 (UTC)",
            "by smtp.kernel.org (Postfix) with ESMTPSA id 082E3C2BCC7;\n\tFri,  8 May 2026 10:55:51 +0000 (UTC)"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1778237755; cv=none;\n b=lsnP49gbE8v/pzRldZ6xb3uE5ifhzvClGDswZzFVh3LflmjDw9EyasnxpYTtesR4VLsTqP3eP8qyB4NHa8Y+8vHPPW90DO0z3hNXUVAxnMI4DhH2pTN+4vkhCBjQZQ9/8vDva0jwChR9+dGh7T9W4K5/Xq6EhdIbthi8w4/JTXA=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1778237755; c=relaxed/simple;\n\tbh=v+BzLZhhFii4PcYFeQkCkVoCdjXrTXNwuPyP+/iYktU=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=Ja9EAQ5ZFQRH8rh22gqIAEoFv/OOAcOrJpy9JAc5pT5A2RbCYPzfzbj1py0OLKLK03cpMIAxY4IxU///g771H7E2FIX4RjnI0X0G6EJkVcBgS5vvFLv3V2h4Gb7gonocZa/2ymfB6XEeAFapnH1GhoBFsIqxRRCvjZC2nqq+oZs=",
        "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=hiZkIDNu; arc=none smtp.client-ip=10.30.226.201",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1778237755;\n\tbh=v+BzLZhhFii4PcYFeQkCkVoCdjXrTXNwuPyP+/iYktU=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=hiZkIDNu4/XbooIFT6MR1tHXJU7X/TQI0HBtTasmGjc71nYFHRtysTkDIZ5BTn1r4\n\t 2q4t7DgMk1QBlOx1vI2ByykZP5P+Y9S08cppbnSzka5IZnNq0KOLzP5wB4ZSdjiZfJ\n\t Wd1TSB5/8gtc+MBUwSIpTUvF+XUqKjgXM+SgGXOYVC0Suqxa1E4lrA2cS5TjHimIOV\n\t NONzFSh5cg9SiV2fOhCJVrkUoKvkb8VE7LV7BIoFC9srueiNkxWuDE8fBRwL19oNyI\n\t 6J4bqlweRM8v5Gcci+4bhkDEBvQWm39N+HkP39XQuDxQoM6BNdWNXmhLZHcjbrDy4u\n\t dykS3NekEqCWA==",
        "From": "Tzung-Bi Shih <tzungbi@kernel.org>",
        "To": "Arnd Bergmann <arnd@arndb.de>,\n\tGreg Kroah-Hartman <gregkh@linuxfoundation.org>,\n\tBartosz Golaszewski <brgl@kernel.org>,\n\tLinus Walleij <linusw@kernel.org>",
        "Cc": "Benson Leung <bleung@chromium.org>,\n\ttzungbi@kernel.org,\n\tlinux-kernel@vger.kernel.org,\n\tchrome-platform@lists.linux.dev,\n\tdriver-core@lists.linux.dev,\n\tlinux-doc@vger.kernel.org,\n\tlinux-gpio@vger.kernel.org,\n\t\"Rafael J. Wysocki\" <rafael@kernel.org>,\n\tDanilo Krummrich <dakr@kernel.org>,\n\tJonathan Corbet <corbet@lwn.net>,\n\tShuah Khan <shuah@kernel.org>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tWolfram Sang <wsa+renesas@sang-engineering.com>,\n\tJason Gunthorpe <jgg@nvidia.com>,\n\tJohan Hovold <johan@kernel.org>,\n\t\"Paul E . McKenney\" <paulmck@kernel.org>",
        "Subject": "[PATCH v10 9/9] platform/chrome: cros_ec_chardev: Consume\n cros_ec_device via revocable",
        "Date": "Fri,  8 May 2026 18:54:48 +0800",
        "Message-ID": "<20260508105448.31799-10-tzungbi@kernel.org>",
        "X-Mailer": "git-send-email 2.51.0",
        "In-Reply-To": "<20260508105448.31799-1-tzungbi@kernel.org>",
        "References": "<20260508105448.31799-1-tzungbi@kernel.org>",
        "Precedence": "bulk",
        "X-Mailing-List": "linux-gpio@vger.kernel.org",
        "List-Id": "<linux-gpio.vger.kernel.org>",
        "List-Subscribe": "<mailto:linux-gpio+subscribe@vger.kernel.org>",
        "List-Unsubscribe": "<mailto:linux-gpio+unsubscribe@vger.kernel.org>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit"
    },
    "content": "The cros_ec_chardev driver provides a character device interface to the\nChromeOS EC.  A file handle to this device can remain open in userspace\neven if the underlying EC device is removed.\n\nThis creates a classic use-after-free vulnerability.  Any file operation\n(ioctl, release, etc.) on the open handle after the EC device has gone\nwould access a stale pointer, leading to a system crash.\n\nTo prevent this, leverage the revocable and convert cros_ec_chardev to a\nresource consumer of cros_ec_device.\n\nSigned-off-by: Tzung-Bi Shih <tzungbi@kernel.org>\n---\nv10:\n- No changes.\n\nv9: https://lore.kernel.org/all/20260427135841.96266-10-tzungbi@kernel.org\n- New to the series.\n- Change revocable API usages accordingly.\n\nv4 - v8:\n- Doesn't exist.\n\nv3: https://lore.kernel.org/all/20250912081718.3827390-6-tzungbi@kernel.org\n- Use specific labels for different cleanup in cros_ec_chardev_open().\n\nv2: https://lore.kernel.org/all/20250820081645.847919-6-tzungbi@kernel.org\n- Rename \"ref_proxy\" -> \"revocable\".\n- Fix a sparse warning by removing the redundant __rcu annotation.\n\nv1: https://lore.kernel.org/all/20250814091020.1302888-4-tzungbi@kernel.org\n\n---\n drivers/platform/chrome/cros_ec_chardev.c | 80 +++++++++++++++++------\n 1 file changed, 61 insertions(+), 19 deletions(-)",
    "diff": "diff --git a/drivers/platform/chrome/cros_ec_chardev.c b/drivers/platform/chrome/cros_ec_chardev.c\nindex 002be3352100..c597dc92d519 100644\n--- a/drivers/platform/chrome/cros_ec_chardev.c\n+++ b/drivers/platform/chrome/cros_ec_chardev.c\n@@ -22,6 +22,7 @@\n #include <linux/platform_data/cros_ec_proto.h>\n #include <linux/platform_device.h>\n #include <linux/poll.h>\n+#include <linux/revocable.h>\n #include <linux/slab.h>\n #include <linux/types.h>\n #include <linux/uaccess.h>\n@@ -32,7 +33,7 @@\n #define CROS_MAX_EVENT_LEN\tPAGE_SIZE\n \n struct chardev_priv {\n-\tstruct cros_ec_device *ec_dev;\n+\tstruct revocable *rev;\n \tstruct notifier_block notifier;\n \twait_queue_head_t wait_event;\n \tunsigned long event_mask;\n@@ -55,6 +56,7 @@ static int ec_get_version(struct chardev_priv *priv, char *str, int maxlen)\n \t};\n \tstruct ec_response_get_version *resp;\n \tstruct cros_ec_command *msg;\n+\tstruct cros_ec_device *ec_dev;\n \tint ret;\n \n \tmsg = kzalloc(sizeof(*msg) + sizeof(*resp), GFP_KERNEL);\n@@ -64,12 +66,19 @@ static int ec_get_version(struct chardev_priv *priv, char *str, int maxlen)\n \tmsg->command = EC_CMD_GET_VERSION + priv->cmd_offset;\n \tmsg->insize = sizeof(*resp);\n \n-\tret = cros_ec_cmd_xfer_status(priv->ec_dev, msg);\n-\tif (ret < 0) {\n-\t\tsnprintf(str, maxlen,\n-\t\t\t \"Unknown EC version, returned error: %d\\n\",\n-\t\t\t msg->result);\n-\t\tgoto exit;\n+\trevocable_try_access_with_scoped(priv->rev, ec_dev) {\n+\t\tif (!ec_dev) {\n+\t\t\tret = -ENODEV;\n+\t\t\tgoto exit;\n+\t\t}\n+\n+\t\tret = cros_ec_cmd_xfer_status(ec_dev, msg);\n+\t\tif (ret < 0) {\n+\t\t\tsnprintf(str, maxlen,\n+\t\t\t\t \"Unknown EC version, returned error: %d\\n\",\n+\t\t\t\t msg->result);\n+\t\t\tgoto exit;\n+\t\t}\n \t}\n \n \tresp = (struct ec_response_get_version *)msg->data;\n@@ -92,10 +101,15 @@ static int cros_ec_chardev_mkbp_event(struct notifier_block *nb,\n {\n \tstruct chardev_priv *priv = container_of(nb, struct chardev_priv,\n \t\t\t\t\t\t notifier);\n-\tstruct cros_ec_device *ec_dev = priv->ec_dev;\n+\tstruct cros_ec_device *ec_dev;\n \tstruct ec_event *event;\n-\tunsigned long event_bit = 1 << ec_dev->event_data.event_type;\n-\tint total_size = sizeof(*event) + ec_dev->event_size;\n+\tunsigned long event_bit;\n+\tint total_size;\n+\n+\trevocable_try_access_or_return_err(priv->rev, ec_dev, NOTIFY_DONE);\n+\n+\tevent_bit = 1 << ec_dev->event_data.event_type;\n+\ttotal_size = sizeof(*event) + ec_dev->event_size;\n \n \tif (!(event_bit & priv->event_mask) ||\n \t    (priv->event_len + total_size) > CROS_MAX_EVENT_LEN)\n@@ -166,7 +180,8 @@ static int cros_ec_chardev_open(struct inode *inode, struct file *filp)\n \tif (!priv)\n \t\treturn -ENOMEM;\n \n-\tpriv->ec_dev = ec_dev;\n+\tpriv->rev = ec_dev->its_rev;\n+\trevocable_get(priv->rev);\n \tpriv->cmd_offset = ec->cmd_offset;\n \tfilp->private_data = priv;\n \tINIT_LIST_HEAD(&priv->events);\n@@ -178,6 +193,7 @@ static int cros_ec_chardev_open(struct inode *inode, struct file *filp)\n \t\t\t\t\t       &priv->notifier);\n \tif (ret) {\n \t\tdev_err(ec_dev->dev, \"failed to register event notifier\\n\");\n+\t\trevocable_put(priv->rev);\n \t\tkfree(priv);\n \t}\n \n@@ -251,11 +267,13 @@ static ssize_t cros_ec_chardev_read(struct file *filp, char __user *buffer,\n static int cros_ec_chardev_release(struct inode *inode, struct file *filp)\n {\n \tstruct chardev_priv *priv = filp->private_data;\n-\tstruct cros_ec_device *ec_dev = priv->ec_dev;\n+\tstruct cros_ec_device *ec_dev;\n \tstruct ec_event *event, *e;\n \n-\tblocking_notifier_chain_unregister(&ec_dev->event_notifier,\n-\t\t\t\t\t   &priv->notifier);\n+\trevocable_try_access_or_skip_scoped(priv->rev, ec_dev)\n+\t\tblocking_notifier_chain_unregister(&ec_dev->event_notifier,\n+\t\t\t\t\t\t   &priv->notifier);\n+\trevocable_put(priv->rev);\n \n \tlist_for_each_entry_safe(event, e, &priv->events, node) {\n \t\tlist_del(&event->node);\n@@ -273,6 +291,7 @@ static long cros_ec_chardev_ioctl_xcmd(struct chardev_priv *priv, void __user *a\n {\n \tstruct cros_ec_command *s_cmd;\n \tstruct cros_ec_command u_cmd;\n+\tstruct cros_ec_device *ec_dev;\n \tlong ret;\n \n \tif (copy_from_user(&u_cmd, arg, sizeof(u_cmd)))\n@@ -299,10 +318,17 @@ static long cros_ec_chardev_ioctl_xcmd(struct chardev_priv *priv, void __user *a\n \t}\n \n \ts_cmd->command += priv->cmd_offset;\n-\tret = cros_ec_cmd_xfer(priv->ec_dev, s_cmd);\n-\t/* Only copy data to userland if data was received. */\n-\tif (ret < 0)\n-\t\tgoto exit;\n+\trevocable_try_access_with_scoped(priv->rev, ec_dev) {\n+\t\tif (!ec_dev) {\n+\t\t\tret = -ENODEV;\n+\t\t\tgoto exit;\n+\t\t}\n+\n+\t\tret = cros_ec_cmd_xfer(ec_dev, s_cmd);\n+\t\t/* Only copy data to userland if data was received. */\n+\t\tif (ret < 0)\n+\t\t\tgoto exit;\n+\t}\n \n \tif (copy_to_user(arg, s_cmd, sizeof(*s_cmd) + s_cmd->insize))\n \t\tret = -EFAULT;\n@@ -313,10 +339,12 @@ static long cros_ec_chardev_ioctl_xcmd(struct chardev_priv *priv, void __user *a\n \n static long cros_ec_chardev_ioctl_readmem(struct chardev_priv *priv, void __user *arg)\n {\n-\tstruct cros_ec_device *ec_dev = priv->ec_dev;\n+\tstruct cros_ec_device *ec_dev;\n \tstruct cros_ec_readmem s_mem = { };\n \tlong num;\n \n+\trevocable_try_access_or_return(priv->rev, ec_dev);\n+\n \t/* Not every platform supports direct reads */\n \tif (!ec_dev->cmd_readmem)\n \t\treturn -ENOTTY;\n@@ -370,11 +398,25 @@ static const struct file_operations chardev_fops = {\n #endif\n };\n \n+static void cros_ec_chardev_free(void *data)\n+{\n+\tstruct revocable *rev = data;\n+\n+\trevocable_put(rev);\n+}\n+\n static int cros_ec_chardev_probe(struct platform_device *pdev)\n {\n \tstruct cros_ec_dev *ec = dev_get_drvdata(pdev->dev.parent);\n \tstruct cros_ec_platform *ec_platform = dev_get_platdata(ec->dev);\n+\tstruct revocable *rev = ec->ec_dev->its_rev;\n \tstruct miscdevice *misc;\n+\tint ret;\n+\n+\trevocable_get(rev);\n+\tret = devm_add_action_or_reset(&pdev->dev, cros_ec_chardev_free, rev);\n+\tif (ret)\n+\t\treturn ret;\n \n \t/* Create a char device: we want to create it anew */\n \tmisc = devm_kzalloc(&pdev->dev, sizeof(*misc), GFP_KERNEL);\n",
    "prefixes": [
        "v10",
        "9/9"
    ]
}