[PATCH 2/3] staging: media: av7110: check dvb_dmxdev_init() result in av7110_register()

From: Andrey Karelin

Date: Mon Nov 02 2026 - 07:53:11 EST


av7110_register() ignores the return value of dvb_dmxdev_init() for both
the main dmxdev and the optional budget-patch dmxdev1. dvb_dmxdev_init()
fails if the demux cannot be opened, the filter array cannot be
allocated or the demux/dvr device cannot be registered. Probing then
continues, and on device removal dvb_unregister() calls
dvb_dmxdev_release(), which dereferences dmxdev->dvbdev and
dmxdev->dvr_dvbdev that are NULL or, if only the dvr device failed to
register, already freed.

Check the result and unwind on failure, releasing the corresponding
demux as well.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Andrey Karelin <a.karelin@xxxxxxxx>
---
drivers/staging/media/av7110/av7110.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/av7110/av7110.c b/drivers/staging/media/av7110/av7110.c
index ecc15bb222c5..3371e33db103 100644
--- a/drivers/staging/media/av7110/av7110.c
+++ b/drivers/staging/media/av7110/av7110.c
@@ -1283,7 +1283,9 @@ static int av7110_register(struct av7110 *av7110)
av7110->dmxdev.demux = &dvbdemux->dmx;
av7110->dmxdev.capabilities = 0;

- dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter);
+ ret = dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter);
+ if (ret < 0)
+ goto err_dmx_release;

av7110->hw_frontend.source = DMX_FRONTEND_0;

@@ -1337,13 +1339,17 @@ static int av7110_register(struct av7110 *av7110)
av7110->dmxdev1.demux = &dvbdemux1->dmx;
av7110->dmxdev1.capabilities = 0;

- dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter);
+ ret = dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter);
+ if (ret < 0)
+ goto err_dmx1_release;

dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
pr_info("additional demux1 for budget-patch registered\n");
}
return 0;

+err_dmx1_release:
+ dvb_dmx_release(&av7110->demux1);
err_unregister:
dvb_net_release(&av7110->dvb_net);
dvb_unregister_device(av7110->osd_dev);
@@ -1351,6 +1357,7 @@ static int av7110_register(struct av7110 *av7110)
av7110_av_unregister(av7110);
err_dmxdev_release:
dvb_dmxdev_release(&av7110->dmxdev);
+err_dmx_release:
dvb_dmx_release(&av7110->demux);
err_registered:
av7110->registered = 0;
--
2.56.0