* [PATCH 0/2] media: i2c: ov7740: Fix remove() teardown and PM runtime
@ 2026-06-15 21:04 Biren Pandya
2026-06-15 21:04 ` [PATCH 1/2] media: i2c: ov7740: Fix use-after-destroy in remove() Biren Pandya
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Biren Pandya @ 2026-06-15 21:04 UTC (permalink / raw)
To: Sakari Ailus, Mauro Carvalho Chehab, linux-media
Cc: linux-kernel, Biren Pandya
This series addresses two severe issues in the teardown path of the
ov7740 image sensor driver.
The first patch addresses a kernel panic caused by a use-after-destroy
on the driver's mutex, exacerbated by a double-free of both the mutex
and the V4L2 control handler.
The second patch modernizes the runtime PM sleep sequence by properly
checking the return value of PM wake operations before issuing I2C
power down sequences, preventing unbalanced PM tracking or hangs on
disconnected devices.
Biren Pandya (2):
media: i2c: ov7740: Fix use-after-destroy in remove()
media: i2c: ov7740: Fix unchecked pm_runtime_get_sync() in remove()
drivers/media/i2c/ov7740.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
--
2.50.1 (Apple Git-155)
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] media: i2c: ov7740: Fix use-after-destroy in remove()
2026-06-15 21:04 [PATCH 0/2] media: i2c: ov7740: Fix remove() teardown and PM runtime Biren Pandya
@ 2026-06-15 21:04 ` Biren Pandya
2026-07-08 8:59 ` Sakari Ailus
2026-06-15 21:04 ` [PATCH 2/2] media: i2c: ov7740: Fix unchecked pm_runtime_get_sync() " Biren Pandya
[not found] ` <20260708125720.27156-4-birenpandya@gmail.com>
2 siblings, 1 reply; 7+ messages in thread
From: Biren Pandya @ 2026-06-15 21:04 UTC (permalink / raw)
To: Sakari Ailus, Mauro Carvalho Chehab, linux-media
Cc: linux-kernel, Biren Pandya
The ov7740_remove() function had a severe teardown order bug where it
destroyed the driver's mutex before freeing the V4L2 control handler
which relies on that mutex, leading to a use-after-destroy kernel panic.
Furthermore, the driver explicitly called v4l2_ctrl_handler_free() and
mutex_destroy() sequentially, but then called ov7740_free_controls()
which invokes both of them a second time, resulting in a double-free.
This patch fixes the issue by unregistering the subdevice first, and
relying exclusively on ov7740_free_controls() to safely tear down the
mutex and control handler in the correct order.
Fixes: 39c5c4471b8d ("media: i2c: Add the ov7740 image sensor driver")
Signed-off-by: Biren Pandya <birenpandya@gmail.com>
---
drivers/media/i2c/ov7740.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
index 632fb80469be..62c124a1353a 100644
--- a/drivers/media/i2c/ov7740.c
+++ b/drivers/media/i2c/ov7740.c
@@ -1116,10 +1116,8 @@ static void ov7740_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
- mutex_destroy(&ov7740->mutex);
- v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
- media_entity_cleanup(&ov7740->subdev.entity);
v4l2_async_unregister_subdev(sd);
+ media_entity_cleanup(&ov7740->subdev.entity);
ov7740_free_controls(ov7740);
pm_runtime_get_sync(&client->dev);
--
2.50.1 (Apple Git-155)
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] media: i2c: ov7740: Fix unchecked pm_runtime_get_sync() in remove()
2026-06-15 21:04 [PATCH 0/2] media: i2c: ov7740: Fix remove() teardown and PM runtime Biren Pandya
2026-06-15 21:04 ` [PATCH 1/2] media: i2c: ov7740: Fix use-after-destroy in remove() Biren Pandya
@ 2026-06-15 21:04 ` Biren Pandya
2026-07-08 8:46 ` Sakari Ailus
[not found] ` <20260708125720.27156-4-birenpandya@gmail.com>
2 siblings, 1 reply; 7+ messages in thread
From: Biren Pandya @ 2026-06-15 21:04 UTC (permalink / raw)
To: Sakari Ailus, Mauro Carvalho Chehab, linux-media
Cc: linux-kernel, Biren Pandya
The ov7740_remove() function unconditionally called pm_runtime_get_sync()
but completely ignored the return value. If the device was already in an
error state or disconnected, this could lead to an unbalanced PM runtime
usage count or attempt to communicate with an unresponsive device.
Replace pm_runtime_get_sync() with pm_runtime_resume_and_get() to ensure
the device actually resumed before attempting to issue I2C power-off
commands, and safely put the PM runtime usage counter.
Signed-off-by: Biren Pandya <birenpandya@gmail.com>
---
drivers/media/i2c/ov7740.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
index 62c124a1353a..6b81882da307 100644
--- a/drivers/media/i2c/ov7740.c
+++ b/drivers/media/i2c/ov7740.c
@@ -1115,17 +1115,20 @@ static void ov7740_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+ int ret;
v4l2_async_unregister_subdev(sd);
media_entity_cleanup(&ov7740->subdev.entity);
ov7740_free_controls(ov7740);
- pm_runtime_get_sync(&client->dev);
+ ret = pm_runtime_resume_and_get(&client->dev);
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
- pm_runtime_put_noidle(&client->dev);
- ov7740_set_power(ov7740, 0);
+ if (ret >= 0) {
+ ov7740_set_power(ov7740, 0);
+ pm_runtime_put_noidle(&client->dev);
+ }
}
static int __maybe_unused ov7740_runtime_suspend(struct device *dev)
--
2.50.1 (Apple Git-155)
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] media: i2c: ov7740: Fix unchecked pm_runtime_get_sync() in remove()
2026-06-15 21:04 ` [PATCH 2/2] media: i2c: ov7740: Fix unchecked pm_runtime_get_sync() " Biren Pandya
@ 2026-07-08 8:46 ` Sakari Ailus
0 siblings, 0 replies; 7+ messages in thread
From: Sakari Ailus @ 2026-07-08 8:46 UTC (permalink / raw)
To: Biren Pandya; +Cc: Mauro Carvalho Chehab, linux-media, linux-kernel
Hi Biren,
On Tue, Jun 16, 2026 at 02:34:12AM +0530, Biren Pandya wrote:
> The ov7740_remove() function unconditionally called pm_runtime_get_sync()
> but completely ignored the return value. If the device was already in an
> error state or disconnected, this could lead to an unbalanced PM runtime
> usage count or attempt to communicate with an unresponsive device.
>
> Replace pm_runtime_get_sync() with pm_runtime_resume_and_get() to ensure
> the device actually resumed before attempting to issue I2C power-off
> commands, and safely put the PM runtime usage counter.
>
> Signed-off-by: Biren Pandya <birenpandya@gmail.com>
> ---
> drivers/media/i2c/ov7740.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
> index 62c124a1353a..6b81882da307 100644
> --- a/drivers/media/i2c/ov7740.c
> +++ b/drivers/media/i2c/ov7740.c
> @@ -1115,17 +1115,20 @@ static void ov7740_remove(struct i2c_client *client)
> {
> struct v4l2_subdev *sd = i2c_get_clientdata(client);
> struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
> + int ret;
>
> v4l2_async_unregister_subdev(sd);
> media_entity_cleanup(&ov7740->subdev.entity);
> ov7740_free_controls(ov7740);
>
> - pm_runtime_get_sync(&client->dev);
> + ret = pm_runtime_resume_and_get(&client->dev);
> pm_runtime_disable(&client->dev);
> pm_runtime_set_suspended(&client->dev);
> - pm_runtime_put_noidle(&client->dev);
>
> - ov7740_set_power(ov7740, 0);
> + if (ret >= 0) {
> + ov7740_set_power(ov7740, 0);
> + pm_runtime_put_noidle(&client->dev);
> + }
Could you do what's done in other drivers, i.e. disable Runtime PM and then
see if the device is active and if so, power it off?
--
Regards,
Sakari Ailus
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] media: i2c: ov7740: Fix use-after-destroy in remove()
2026-06-15 21:04 ` [PATCH 1/2] media: i2c: ov7740: Fix use-after-destroy in remove() Biren Pandya
@ 2026-07-08 8:59 ` Sakari Ailus
0 siblings, 0 replies; 7+ messages in thread
From: Sakari Ailus @ 2026-07-08 8:59 UTC (permalink / raw)
To: Biren Pandya; +Cc: Mauro Carvalho Chehab, linux-media, linux-kernel
Hi Biren,
On Tue, Jun 16, 2026 at 02:34:11AM +0530, Biren Pandya wrote:
> The ov7740_remove() function had a severe teardown order bug where it
> destroyed the driver's mutex before freeing the V4L2 control handler
> which relies on that mutex, leading to a use-after-destroy kernel panic.
> Furthermore, the driver explicitly called v4l2_ctrl_handler_free() and
> mutex_destroy() sequentially, but then called ov7740_free_controls()
> which invokes both of them a second time, resulting in a double-free.
>
> This patch fixes the issue by unregistering the subdevice first, and
> relying exclusively on ov7740_free_controls() to safely tear down the
> mutex and control handler in the correct order.
>
> Fixes: 39c5c4471b8d ("media: i2c: Add the ov7740 image sensor driver")
> Signed-off-by: Biren Pandya <birenpandya@gmail.com>
Can you add Cc: stable... for v2, please?
> ---
> drivers/media/i2c/ov7740.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
> index 632fb80469be..62c124a1353a 100644
> --- a/drivers/media/i2c/ov7740.c
> +++ b/drivers/media/i2c/ov7740.c
> @@ -1116,10 +1116,8 @@ static void ov7740_remove(struct i2c_client *client)
> struct v4l2_subdev *sd = i2c_get_clientdata(client);
> struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
>
> - mutex_destroy(&ov7740->mutex);
> - v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
> - media_entity_cleanup(&ov7740->subdev.entity);
> v4l2_async_unregister_subdev(sd);
> + media_entity_cleanup(&ov7740->subdev.entity);
> ov7740_free_controls(ov7740);
>
> pm_runtime_get_sync(&client->dev);
--
Kind regards,
Sakari Ailus
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/2] media: i2c: ov7740: fix unbalanced pm_runtime_get_sync in remove
[not found] ` <20260708125720.27156-4-birenpandya@gmail.com>
@ 2026-07-08 12:57 ` Biren Pandya
2026-07-08 12:57 ` [PATCH v2 2/2] media: i2c: ov7740: fix use-after-destroy " Biren Pandya
1 sibling, 0 replies; 7+ messages in thread
From: Biren Pandya @ 2026-07-08 12:57 UTC (permalink / raw)
To: sakari.ailus, mchehab, linux-media, linux-kernel; +Cc: Biren Pandya
The ov7740_remove() function unconditionally called pm_runtime_get_sync()
but completely ignored the return value. If the device was already in an
error state or disconnected, this could lead to an unbalanced PM runtime
usage count or attempt to communicate with an unresponsive device.
Disable Runtime PM first, then see if the device is active, and if so,
power it off.
Signed-off-by: Biren Pandya <birenpandya@gmail.com>
---
v2: disabled PM before conditionally powering off as per standard pattern (Sakari).
---
drivers/media/i2c/ov7740.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
index c2e02f1918169..2d29147c0f647 100644
--- a/drivers/media/i2c/ov7740.c
+++ b/drivers/media/i2c/ov7740.c
@@ -1122,12 +1122,10 @@ static void ov7740_remove(struct i2c_client *client)
v4l2_async_unregister_subdev(sd);
ov7740_free_controls(ov7740);
- pm_runtime_get_sync(&client->dev);
pm_runtime_disable(&client->dev);
+ if (!pm_runtime_status_suspended(&client->dev))
+ ov7740_set_power(ov7740, 0);
pm_runtime_set_suspended(&client->dev);
- pm_runtime_put_noidle(&client->dev);
-
- ov7740_set_power(ov7740, 0);
}
static int __maybe_unused ov7740_runtime_suspend(struct device *dev)
--
2.50.1 (Apple Git-155)
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/2] media: i2c: ov7740: fix use-after-destroy in remove
[not found] ` <20260708125720.27156-4-birenpandya@gmail.com>
2026-07-08 12:57 ` [PATCH v2 1/2] media: i2c: ov7740: fix unbalanced pm_runtime_get_sync in remove Biren Pandya
@ 2026-07-08 12:57 ` Biren Pandya
1 sibling, 0 replies; 7+ messages in thread
From: Biren Pandya @ 2026-07-08 12:57 UTC (permalink / raw)
To: sakari.ailus, mchehab, songjun.wu, wenyou.yang, linux-media,
linux-kernel
Cc: Biren Pandya, stable
The ov7740_remove() function had a severe teardown order bug where it
destroyed the driver's mutex before freeing the V4L2 control handler
which relies on that mutex, leading to a use-after-destroy kernel panic.
Furthermore, the driver explicitly called v4l2_ctrl_handler_free() and
mutex_destroy() sequentially, but then called ov7740_free_controls()
which invokes both of them a second time, resulting in a double-free.
This patch fixes the issue by unregistering the subdevice first, and
relying exclusively on ov7740_free_controls() to safely tear down the
mutex and control handler in the correct order.
Fixes: 39c5c4471b8d ("media: i2c: Add the ov7740 image sensor driver")
Cc: stable@vger.kernel.org
Signed-off-by: Biren Pandya <birenpandya@gmail.com>
---
v2: added Fixes and Cc stable tags.
---
drivers/media/i2c/ov7740.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
index 2d29147c0f647..b4e14171556f9 100644
--- a/drivers/media/i2c/ov7740.c
+++ b/drivers/media/i2c/ov7740.c
@@ -1116,10 +1116,8 @@ static void ov7740_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
- mutex_destroy(&ov7740->mutex);
- v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
- media_entity_cleanup(&ov7740->subdev.entity);
v4l2_async_unregister_subdev(sd);
+ media_entity_cleanup(&ov7740->subdev.entity);
ov7740_free_controls(ov7740);
pm_runtime_disable(&client->dev);
--
2.50.1 (Apple Git-155)
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-08 12:57 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-15 21:04 [PATCH 0/2] media: i2c: ov7740: Fix remove() teardown and PM runtime Biren Pandya
2026-06-15 21:04 ` [PATCH 1/2] media: i2c: ov7740: Fix use-after-destroy in remove() Biren Pandya
2026-07-08 8:59 ` Sakari Ailus
2026-06-15 21:04 ` [PATCH 2/2] media: i2c: ov7740: Fix unchecked pm_runtime_get_sync() " Biren Pandya
2026-07-08 8:46 ` Sakari Ailus
[not found] ` <20260708125720.27156-4-birenpandya@gmail.com>
2026-07-08 12:57 ` [PATCH v2 1/2] media: i2c: ov7740: fix unbalanced pm_runtime_get_sync in remove Biren Pandya
2026-07-08 12:57 ` [PATCH v2 2/2] media: i2c: ov7740: fix use-after-destroy " Biren Pandya
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox