From: "Damien Riégel" <damien.riegel@silabs.com>
To: Johan Hovold <johan@kernel.org>, Alex Elder <elder@kernel.org>,
Dan Carpenter <dan.carpenter@linaro.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
greybus-dev@lists.linaro.org, linux-staging@lists.linux.dev,
linux-kernel@vger.kernel.org
Cc: "Damien Riégel" <damien.riegel@silabs.com>
Subject: [PATCH v3 2/2] greybus: raw: fix use-after-free if write is called after disconnect
Date: Mon, 23 Mar 2026 22:25:10 -0400 [thread overview]
Message-ID: <20260324022510.28596-2-damien.riegel@silabs.com> (raw)
In-Reply-To: <20260324022510.28596-1-damien.riegel@silabs.com>
If a user writes to the chardev after disconnect has been called, the
kernel panics with the following trace (with
CONFIG_INIT_ON_FREE_DEFAULT_ON=y):
BUG: kernel NULL pointer dereference, address: 0000000000000218
...
Call Trace:
<TASK>
gb_operation_create_common+0x61/0x180
gb_operation_create_flags+0x28/0xa0
gb_operation_sync_timeout+0x6f/0x100
raw_write+0x7b/0xc7 [gb_raw]
vfs_write+0xcf/0x420
? task_mm_cid_work+0x136/0x220
ksys_write+0x63/0xe0
do_syscall_64+0xa4/0x290
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Disconnect calls gb_connection_destroy, which ends up freeing the
connection object. When gb_operation_sync is called in the write file
operations, its gets a freed connection as parameter and the kernel
panics.
The gb_connection_destroy cannot be moved out of the disconnect
function, as the Greybus subsystem expect all connections belonging to a
bundle to be destroyed when disconnect returns.
To prevent this bug, use a rw lock to synchronize access between write
and disconnect. This guarantees that the write function doesn't try
to use a disconnected connection.
Fixes: e806c7fb8e9b ("greybus: raw: add raw greybus kernel driver")
Signed-off-by: Damien Riégel <damien.riegel@silabs.com>
---
Changes in v3:
- rename "connected" flag to "disconnected"
- acquire/release of write semaphore acquire/release were in
gb_raw_send, move them to the caller instead (raw_write)
Changes in v2:
- trim down trace in commit message to keep only the essential part
- convert the mutex that protected the connection to a rw_semaphore
- use a "connected" flag instead of relying on the connection pointer
being NULL or not
drivers/staging/greybus/raw.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/greybus/raw.c b/drivers/staging/greybus/raw.c
index e668438e1a2..1e7ffa10a50 100644
--- a/drivers/staging/greybus/raw.c
+++ b/drivers/staging/greybus/raw.c
@@ -21,6 +21,8 @@ struct gb_raw {
struct list_head list;
int list_data;
struct mutex list_lock;
+ struct rw_semaphore disconnect_lock;
+ bool disconnected;
struct cdev cdev;
struct device dev;
};
@@ -200,6 +202,7 @@ static int gb_raw_probe(struct gb_bundle *bundle,
INIT_LIST_HEAD(&raw->list);
mutex_init(&raw->list_lock);
+ init_rwsem(&raw->disconnect_lock);
raw->connection = connection;
greybus_set_drvdata(bundle, raw);
@@ -235,6 +238,11 @@ static void gb_raw_disconnect(struct gb_bundle *bundle)
struct raw_data *temp;
cdev_device_del(&raw->cdev, &raw->dev);
+
+ down_write(&raw->disconnect_lock);
+ raw->disconnected = true;
+ up_write(&raw->disconnect_lock);
+
gb_connection_disable(connection);
gb_connection_destroy(connection);
@@ -277,11 +285,20 @@ static ssize_t raw_write(struct file *file, const char __user *buf,
if (count > MAX_PACKET_SIZE)
return -E2BIG;
- retval = gb_raw_send(raw, count, buf);
- if (retval)
- return retval;
+ down_read(&raw->disconnect_lock);
- return count;
+ if (raw->disconnected) {
+ retval = -ENODEV;
+ goto exit;
+ }
+
+ retval = gb_raw_send(raw, count, buf);
+ if (!retval)
+ retval = count;
+exit:
+ up_read(&raw->disconnect_lock);
+
+ return retval;
}
static ssize_t raw_read(struct file *file, char __user *buf, size_t count,
--
2.52.0
next prev parent reply other threads:[~2026-03-24 2:38 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-24 2:25 [PATCH v3 1/2] greybus: raw: fix use-after-free on cdev close Damien Riégel
2026-03-24 2:25 ` Damien Riégel [this message]
2026-03-24 7:52 ` [PATCH v3 2/2] greybus: raw: fix use-after-free if write is called after disconnect Johan Hovold
2026-03-24 8:03 ` Johan Hovold
2026-03-24 7:45 ` [PATCH v3 1/2] greybus: raw: fix use-after-free on cdev close Johan Hovold
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260324022510.28596-2-damien.riegel@silabs.com \
--to=damien.riegel@silabs.com \
--cc=dan.carpenter@linaro.org \
--cc=elder@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=greybus-dev@lists.linaro.org \
--cc=johan@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-staging@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.