get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2228941,
    "url": "http://patchwork.ozlabs.org/api/1.1/patches/2228941/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/patch/20260427135841.96266-10-tzungbi@kernel.org/",
    "project": {
        "id": 42,
        "url": "http://patchwork.ozlabs.org/api/1.1/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": ""
    },
    "msgid": "<20260427135841.96266-10-tzungbi@kernel.org>",
    "date": "2026-04-27T13:58:41",
    "name": "[v9,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.1/people/83557/?format=api",
        "name": "Tzung-Bi Shih",
        "email": "tzungbi@kernel.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-gpio/patch/20260427135841.96266-10-tzungbi@kernel.org/mbox/",
    "series": [
        {
            "id": 501655,
            "url": "http://patchwork.ozlabs.org/api/1.1/series/501655/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/list/?series=501655",
            "date": "2026-04-27T13:58:32",
            "name": "drivers/base: Introduce revocable",
            "version": 9,
            "mbox": "http://patchwork.ozlabs.org/series/501655/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2228941/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2228941/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "\n <linux-gpio+bounces-35582-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=XZVjs1KP;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-gpio+bounces-35582-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=\"XZVjs1KP\"",
            "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201"
        ],
        "Received": [
            "from sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\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 4g453T3xBSz1xvV\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 28 Apr 2026 00:07:01 +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 D4CAB303A85E\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 27 Apr 2026 14:00:30 +0000 (UTC)",
            "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 645463D3D1E;\n\tMon, 27 Apr 2026 14:00:05 +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 234BE3D3D08;\n\tMon, 27 Apr 2026 14:00:05 +0000 (UTC)",
            "by smtp.kernel.org (Postfix) with ESMTPSA id 58B7AC19425;\n\tMon, 27 Apr 2026 14:00:01 +0000 (UTC)"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1777298405; cv=none;\n b=FYsRUiq5SQWKj6gWsVjX+ouXB0ZyNnXWFEtraDoYxKa8wc3BhpaOCggCaol8UdqCHmgeLTheDi3r/OrxUnRECPknpa6DTml+GcOJWxefeiw4bc5mNcCVtd0k5kTHQHYfVe0Hss7beP/1qoqT8x6NTEwlAduW8WFvyK4TQuxstwg=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1777298405; c=relaxed/simple;\n\tbh=1M7X8jOCHkeLS6fn4xzZWtWs67rOTDG2AL/8546NOlk=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=FATFuPpyLc+BACxXi7d8AGSdVfx8Og1ECWGmdTDdWetNhpqCRVIRZiHEqLQbyiiqSHYpjgoU8Nz9x7qo5Oa3hO5+sR1/jJ/7DHWNJGJYqGtVzvo+di7w2oGs/c1k3+uzYK8viIILpX53DTmxG8S8oGBwUzFiPzRG1oXk74f4J6k=",
        "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=XZVjs1KP; 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=1777298405;\n\tbh=1M7X8jOCHkeLS6fn4xzZWtWs67rOTDG2AL/8546NOlk=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=XZVjs1KPQbSj9+RUKCOXJI1F/eTohGWVETAO4evJbYcbtUxFKs5RJynM0j9ejwFAf\n\t 0jgut4X+sdR7AToiMV9NyVJl5tkD79BLCfYXUxyXjECd/hL8ODyNqSF48s4vivIfUD\n\t epZxGxpb2jvXFxQeSGXRTer8E0Vq/uzHQU4hBUn5Rc1N7Sopw/wxShbS+JzaFFYs1l\n\t o7FtLFoLTXY5hqzAg4y6VOYt6zvm/X82ysLFmhTVB4Zpk41E4/P0YTZY/Bvdu/l4hr\n\t GT4HaTFNfyCSjHS3xnMSeICctwD16/ZyGhKW6a91+d1Aup5GRwcJfgs7Rt19gA4phi\n\t qaAemgtOjOVJA==",
        "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>,\n\tDan Williams <dan.j.williams@intel.com>",
        "Subject": "[PATCH v9 9/9] platform/chrome: cros_ec_chardev: Consume\n cros_ec_device via revocable",
        "Date": "Mon, 27 Apr 2026 21:58:41 +0800",
        "Message-ID": "<20260427135841.96266-10-tzungbi@kernel.org>",
        "X-Mailer": "git-send-email 2.51.0",
        "In-Reply-To": "<20260427135841.96266-1-tzungbi@kernel.org>",
        "References": "<20260427135841.96266-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---\nv9:\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": [
        "v9",
        "9/9"
    ]
}