linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH AUTOSEL 4.14 03/20] media: dvb-usb: az6027: fix three null-ptr-deref in az6027_i2c_xfer()
       [not found] <20230525184520.2004878-1-sashal@kernel.org>
@ 2023-05-25 18:44 ` Sasha Levin
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 04/20] media: dvb-usb-v2: ec168: fix null-ptr-deref in ec168_i2c_xfer() Sasha Levin
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Sasha Levin @ 2023-05-25 18:44 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Wei Chen, Mauro Carvalho Chehab, Sasha Levin, zhongbaisong, linux-media

From: Wei Chen <harperchen1110@gmail.com>

[ Upstream commit 858e97d7956d17a2cb56a9413468704a4d5abfe1 ]

In az6027_i2c_xfer, msg is controlled by user. When msg[i].buf is null,
commit 0ed554fd769a ("media: dvb-usb: az6027: fix null-ptr-deref in
az6027_i2c_xfer()") fix the null-ptr-deref bug when msg[i].addr is 0x99.
However, null-ptr-deref also happens when msg[i].addr is 0xd0 and 0xc0.
We add check on msg[i].len to prevent null-ptr-deref.

Link: https://lore.kernel.org/linux-media/20230310165604.3093483-1-harperchen1110@gmail.com
Signed-off-by: Wei Chen <harperchen1110@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/media/usb/dvb-usb/az6027.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
index f2b5ba1d28098..05988c5ce63ca 100644
--- a/drivers/media/usb/dvb-usb/az6027.c
+++ b/drivers/media/usb/dvb-usb/az6027.c
@@ -991,6 +991,10 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
 			/* write/read request */
 			if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
 				req = 0xB9;
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
 				value = msg[i].addr + (msg[i].len << 8);
 				length = msg[i + 1].len + 6;
@@ -1004,6 +1008,10 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
 
 				/* demod 16bit addr */
 				req = 0xBD;
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
 				value = msg[i].addr + (2 << 8);
 				length = msg[i].len - 2;
@@ -1029,6 +1037,10 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
 			} else {
 
 				req = 0xBD;
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				index = msg[i].buf[0] & 0x00FF;
 				value = msg[i].addr + (1 << 8);
 				length = msg[i].len - 1;
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH AUTOSEL 4.14 04/20] media: dvb-usb-v2: ec168: fix null-ptr-deref in ec168_i2c_xfer()
       [not found] <20230525184520.2004878-1-sashal@kernel.org>
  2023-05-25 18:44 ` [PATCH AUTOSEL 4.14 03/20] media: dvb-usb: az6027: fix three null-ptr-deref in az6027_i2c_xfer() Sasha Levin
@ 2023-05-25 18:45 ` Sasha Levin
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 05/20] media: dvb-usb-v2: ce6230: fix null-ptr-deref in ce6230_i2c_master_xfer() Sasha Levin
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Sasha Levin @ 2023-05-25 18:45 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Wei Chen, Mauro Carvalho Chehab, Sasha Levin, crope, linux-media

From: Wei Chen <harperchen1110@gmail.com>

[ Upstream commit a6dcefcc08eca1bf4e3d213c97c3cfb75f377935 ]

In ec168_i2c_xfer, msg is controlled by user. When msg[i].buf is null
and msg[i].len is zero, former checks on msg[i].buf would be passed.
If accessing msg[i].buf[0] without sanity check, null pointer deref
would happen. We add check on msg[i].len to prevent crash.

Similar commit:
commit 0ed554fd769a ("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()")

Link: https://lore.kernel.org/linux-media/20230313085853.3252349-1-harperchen1110@gmail.com
Signed-off-by: Wei Chen <harperchen1110@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/media/usb/dvb-usb-v2/ec168.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/media/usb/dvb-usb-v2/ec168.c b/drivers/media/usb/dvb-usb-v2/ec168.c
index 1db8aeef36553..19605958501e1 100644
--- a/drivers/media/usb/dvb-usb-v2/ec168.c
+++ b/drivers/media/usb/dvb-usb-v2/ec168.c
@@ -125,6 +125,10 @@ static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 	while (i < num) {
 		if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
 			if (msg[i].addr == ec168_ec100_config.demod_address) {
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				req.cmd = READ_DEMOD;
 				req.value = 0;
 				req.index = 0xff00 + msg[i].buf[0]; /* reg */
@@ -141,6 +145,10 @@ static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 			}
 		} else {
 			if (msg[i].addr == ec168_ec100_config.demod_address) {
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				req.cmd = WRITE_DEMOD;
 				req.value = msg[i].buf[1]; /* val */
 				req.index = 0xff00 + msg[i].buf[0]; /* reg */
@@ -149,6 +157,10 @@ static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 				ret = ec168_ctrl_msg(d, &req);
 				i += 1;
 			} else {
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				req.cmd = WRITE_I2C;
 				req.value = msg[i].buf[0]; /* val */
 				req.index = 0x0100 + msg[i].addr; /* I2C addr */
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH AUTOSEL 4.14 05/20] media: dvb-usb-v2: ce6230: fix null-ptr-deref in ce6230_i2c_master_xfer()
       [not found] <20230525184520.2004878-1-sashal@kernel.org>
  2023-05-25 18:44 ` [PATCH AUTOSEL 4.14 03/20] media: dvb-usb: az6027: fix three null-ptr-deref in az6027_i2c_xfer() Sasha Levin
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 04/20] media: dvb-usb-v2: ec168: fix null-ptr-deref in ec168_i2c_xfer() Sasha Levin
@ 2023-05-25 18:45 ` Sasha Levin
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 06/20] media: dvb-usb-v2: rtl28xxu: fix null-ptr-deref in rtl28xxu_i2c_xfer Sasha Levin
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Sasha Levin @ 2023-05-25 18:45 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Wei Chen, Mauro Carvalho Chehab, Sasha Levin, crope, linux-media

From: Wei Chen <harperchen1110@gmail.com>

[ Upstream commit dff919090155fb22679869e8469168f270dcd97f ]

In ce6230_i2c_master_xfer, msg is controlled by user. When msg[i].buf
is null and msg[i].len is zero, former checks on msg[i].buf would be
passed. Malicious data finally reach ce6230_i2c_master_xfer. If accessing
msg[i].buf[0] without sanity check, null ptr deref would happen. We add
check on msg[i].len to prevent crash.

Similar commit:
commit 0ed554fd769a ("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()")

Link: https://lore.kernel.org/linux-media/20230313092751.209496-1-harperchen1110@gmail.com
Signed-off-by: Wei Chen <harperchen1110@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/media/usb/dvb-usb-v2/ce6230.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/media/usb/dvb-usb-v2/ce6230.c b/drivers/media/usb/dvb-usb-v2/ce6230.c
index e596031a708d0..80a07aab3b4b0 100644
--- a/drivers/media/usb/dvb-usb-v2/ce6230.c
+++ b/drivers/media/usb/dvb-usb-v2/ce6230.c
@@ -111,6 +111,10 @@ static int ce6230_i2c_master_xfer(struct i2c_adapter *adap,
 		if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
 			if (msg[i].addr ==
 				ce6230_zl10353_config.demod_address) {
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				req.cmd = DEMOD_READ;
 				req.value = msg[i].addr >> 1;
 				req.index = msg[i].buf[0];
@@ -127,6 +131,10 @@ static int ce6230_i2c_master_xfer(struct i2c_adapter *adap,
 		} else {
 			if (msg[i].addr ==
 				ce6230_zl10353_config.demod_address) {
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				req.cmd = DEMOD_WRITE;
 				req.value = msg[i].addr >> 1;
 				req.index = msg[i].buf[0];
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH AUTOSEL 4.14 06/20] media: dvb-usb-v2: rtl28xxu: fix null-ptr-deref in rtl28xxu_i2c_xfer
       [not found] <20230525184520.2004878-1-sashal@kernel.org>
                   ` (2 preceding siblings ...)
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 05/20] media: dvb-usb-v2: ce6230: fix null-ptr-deref in ce6230_i2c_master_xfer() Sasha Levin
@ 2023-05-25 18:45 ` Sasha Levin
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 07/20] media: dvb-usb: digitv: fix null-ptr-deref in digitv_i2c_xfer() Sasha Levin
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Sasha Levin @ 2023-05-25 18:45 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Zhang Shurong, Mauro Carvalho Chehab, Sasha Levin, crope, linux-media

From: Zhang Shurong <zhang_shurong@foxmail.com>

[ Upstream commit aa4a447b81b84f69c1a89ad899df157f386d7636 ]

In rtl28xxu_i2c_xfer, msg is controlled by user. When msg[i].buf
is null and msg[i].len is zero, former checks on msg[i].buf would be
passed. Malicious data finally reach rtl28xxu_i2c_xfer. If accessing
msg[i].buf[0] without sanity check, null ptr deref would happen.
We add check on msg[i].len to prevent crash.

Similar commit:
commit 0ed554fd769a
("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()")

Link: https://lore.kernel.org/linux-media/tencent_3623572106754AC2F266B316798B0F6CCA05@qq.com
Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index bfce2d6addf7e..5c0ad2dc315a5 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -189,6 +189,10 @@ static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 			ret = -EOPNOTSUPP;
 			goto err_mutex_unlock;
 		} else if (msg[0].addr == 0x10) {
+			if (msg[0].len < 1 || msg[1].len < 1) {
+				ret = -EOPNOTSUPP;
+				goto err_mutex_unlock;
+			}
 			/* method 1 - integrated demod */
 			if (msg[0].buf[0] == 0x00) {
 				/* return demod page from driver cache */
@@ -202,6 +206,10 @@ static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 				ret = rtl28xxu_ctrl_msg(d, &req);
 			}
 		} else if (msg[0].len < 2) {
+			if (msg[0].len < 1) {
+				ret = -EOPNOTSUPP;
+				goto err_mutex_unlock;
+			}
 			/* method 2 - old I2C */
 			req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
 			req.index = CMD_I2C_RD;
@@ -230,8 +238,16 @@ static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 			ret = -EOPNOTSUPP;
 			goto err_mutex_unlock;
 		} else if (msg[0].addr == 0x10) {
+			if (msg[0].len < 1) {
+				ret = -EOPNOTSUPP;
+				goto err_mutex_unlock;
+			}
 			/* method 1 - integrated demod */
 			if (msg[0].buf[0] == 0x00) {
+				if (msg[0].len < 2) {
+					ret = -EOPNOTSUPP;
+					goto err_mutex_unlock;
+				}
 				/* save demod page for later demod access */
 				dev->page = msg[0].buf[1];
 				ret = 0;
@@ -244,6 +260,10 @@ static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 				ret = rtl28xxu_ctrl_msg(d, &req);
 			}
 		} else if ((msg[0].len < 23) && (!dev->new_i2c_write)) {
+			if (msg[0].len < 1) {
+				ret = -EOPNOTSUPP;
+				goto err_mutex_unlock;
+			}
 			/* method 2 - old I2C */
 			req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
 			req.index = CMD_I2C_WR;
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH AUTOSEL 4.14 07/20] media: dvb-usb: digitv: fix null-ptr-deref in digitv_i2c_xfer()
       [not found] <20230525184520.2004878-1-sashal@kernel.org>
                   ` (3 preceding siblings ...)
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 06/20] media: dvb-usb-v2: rtl28xxu: fix null-ptr-deref in rtl28xxu_i2c_xfer Sasha Levin
@ 2023-05-25 18:45 ` Sasha Levin
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 08/20] media: dvb-usb: dw2102: fix uninit-value in su3000_read_mac_address Sasha Levin
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Sasha Levin @ 2023-05-25 18:45 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Wei Chen, Mauro Carvalho Chehab, Sasha Levin, linux-media

From: Wei Chen <harperchen1110@gmail.com>

[ Upstream commit 9ded5bd2a49ce3015b7c936743eec0a0e6e11f0c ]

In digitv_i2c_xfer, msg is controlled by user. When msg[i].buf
is null and msg[i].len is zero, former checks on msg[i].buf would be
passed. Malicious data finally reach digitv_i2c_xfer. If accessing
msg[i].buf[0] without sanity check, null ptr deref would happen. We add
check on msg[i].len to prevent crash.

Similar commit:
commit 0ed554fd769a ("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()")

Link: https://lore.kernel.org/linux-media/20230313095008.1039689-1-harperchen1110@gmail.com
Signed-off-by: Wei Chen <harperchen1110@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/media/usb/dvb-usb/digitv.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/usb/dvb-usb/digitv.c b/drivers/media/usb/dvb-usb/digitv.c
index 20d33f0544ed2..0e2cffa946f69 100644
--- a/drivers/media/usb/dvb-usb/digitv.c
+++ b/drivers/media/usb/dvb-usb/digitv.c
@@ -66,6 +66,10 @@ static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
 		warn("more than 2 i2c messages at a time is not handled yet. TODO.");
 
 	for (i = 0; i < num; i++) {
+		if (msg[i].len < 1) {
+			i = -EOPNOTSUPP;
+			break;
+		}
 		/* write/read request */
 		if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
 			if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0,
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH AUTOSEL 4.14 08/20] media: dvb-usb: dw2102: fix uninit-value in su3000_read_mac_address
       [not found] <20230525184520.2004878-1-sashal@kernel.org>
                   ` (4 preceding siblings ...)
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 07/20] media: dvb-usb: digitv: fix null-ptr-deref in digitv_i2c_xfer() Sasha Levin
@ 2023-05-25 18:45 ` Sasha Levin
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 09/20] media: netup_unidvb: fix irq init by register it at the end of probe Sasha Levin
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Sasha Levin @ 2023-05-25 18:45 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Wei Chen, Mauro Carvalho Chehab, Sasha Levin, linux-media

From: Wei Chen <harperchen1110@gmail.com>

[ Upstream commit a3fd1ef27aa686d871cefe207bd6168c4b0cd29e ]

In su3000_read_mac_address, if i2c_transfer fails to execute two
messages, array mac address will not be initialized. Without handling
such error, later in function dvb_usb_adapter_dvb_init, proposed_mac
is accessed before initialization.

Fix this error by returning a negative value if message execution fails.

Link: https://lore.kernel.org/linux-media/20230328124416.560889-1-harperchen1110@gmail.com
Signed-off-by: Wei Chen <harperchen1110@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/media/usb/dvb-usb/dw2102.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
index 98770a95721b9..2c9c4432a0e65 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -951,7 +951,7 @@ static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
 	for (i = 0; i < 6; i++) {
 		obuf[1] = 0xf0 + i;
 		if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
-			break;
+			return -1;
 		else
 			mac[i] = ibuf[0];
 	}
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH AUTOSEL 4.14 09/20] media: netup_unidvb: fix irq init by register it at the end of probe
       [not found] <20230525184520.2004878-1-sashal@kernel.org>
                   ` (5 preceding siblings ...)
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 08/20] media: dvb-usb: dw2102: fix uninit-value in su3000_read_mac_address Sasha Levin
@ 2023-05-25 18:45 ` Sasha Levin
  2023-06-16 19:20   ` Pavel Machek
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 10/20] media: ttusb-dec: fix memory leak in ttusb_dec_exit_dvb() Sasha Levin
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 11+ messages in thread
From: Sasha Levin @ 2023-05-25 18:45 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Wei Chen, Mauro Carvalho Chehab, Sasha Levin, serjk, aospan, linux-media

From: Wei Chen <harperchen1110@gmail.com>

[ Upstream commit e6ad6233592593079db5c8fa592c298e51bc1356 ]

IRQ handler netup_spi_interrupt() takes spinlock spi->lock. The lock
is initialized in netup_spi_init(). However, irq handler is registered
before initializing the lock.

Spinlock dma->lock and i2c->lock suffer from the same problem.

Fix this by registering the irq at the end of probe.

Link: https://lore.kernel.org/linux-media/20230315134518.1074497-1-harperchen1110@gmail.com
Signed-off-by: Wei Chen <harperchen1110@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 .../media/pci/netup_unidvb/netup_unidvb_core.c  | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
index 03239fba87bf2..0da29f085c10f 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
@@ -897,12 +897,7 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev,
 		ndev->lmmio0, (u32)pci_resource_len(pci_dev, 0),
 		ndev->lmmio1, (u32)pci_resource_len(pci_dev, 1),
 		pci_dev->irq);
-	if (request_irq(pci_dev->irq, netup_unidvb_isr, IRQF_SHARED,
-			"netup_unidvb", pci_dev) < 0) {
-		dev_err(&pci_dev->dev,
-			"%s(): can't get IRQ %d\n", __func__, pci_dev->irq);
-		goto irq_request_err;
-	}
+
 	ndev->dma_size = 2 * 188 *
 		NETUP_DMA_BLOCKS_COUNT * NETUP_DMA_PACKETS_COUNT;
 	ndev->dma_virt = dma_alloc_coherent(&pci_dev->dev,
@@ -943,6 +938,14 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev,
 		dev_err(&pci_dev->dev, "netup_unidvb: DMA setup failed\n");
 		goto dma_setup_err;
 	}
+
+	if (request_irq(pci_dev->irq, netup_unidvb_isr, IRQF_SHARED,
+			"netup_unidvb", pci_dev) < 0) {
+		dev_err(&pci_dev->dev,
+			"%s(): can't get IRQ %d\n", __func__, pci_dev->irq);
+		goto dma_setup_err;
+	}
+
 	dev_info(&pci_dev->dev,
 		"netup_unidvb: device has been initialized\n");
 	return 0;
@@ -961,8 +964,6 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev,
 	dma_free_coherent(&pci_dev->dev, ndev->dma_size,
 			ndev->dma_virt, ndev->dma_phys);
 dma_alloc_err:
-	free_irq(pci_dev->irq, pci_dev);
-irq_request_err:
 	iounmap(ndev->lmmio1);
 pci_bar1_error:
 	iounmap(ndev->lmmio0);
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH AUTOSEL 4.14 10/20] media: ttusb-dec: fix memory leak in ttusb_dec_exit_dvb()
       [not found] <20230525184520.2004878-1-sashal@kernel.org>
                   ` (6 preceding siblings ...)
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 09/20] media: netup_unidvb: fix irq init by register it at the end of probe Sasha Levin
@ 2023-05-25 18:45 ` Sasha Levin
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 11/20] media: dvb-core: Fix kernel WARNING for blocking operation in wait_event*() Sasha Levin
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 12/20] media: dvb-core: Fix use-after-free due to race condition at dvb_ca_en50221 Sasha Levin
  9 siblings, 0 replies; 11+ messages in thread
From: Sasha Levin @ 2023-05-25 18:45 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Hyunwoo Kim, Mauro Carvalho Chehab, Sasha Levin, linux-media

From: Hyunwoo Kim <imv4bel@gmail.com>

[ Upstream commit 517a281338322ff8293f988771c98aaa7205e457 ]

Since dvb_frontend_detach() is not called in ttusb_dec_exit_dvb(),
which is called when the device is disconnected, dvb_frontend_free()
is not finally called.

This causes a memory leak just by repeatedly plugging and
unplugging the device.

Fix this issue by adding dvb_frontend_detach() to ttusb_dec_exit_dvb().

Link: https://lore.kernel.org/linux-media/20221117045925.14297-5-imv4bel@gmail.com
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/media/usb/ttusb-dec/ttusb_dec.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c
index cad2746158160..d41ba80881759 100644
--- a/drivers/media/usb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c
@@ -1571,8 +1571,7 @@ static void ttusb_dec_exit_dvb(struct ttusb_dec *dec)
 	dvb_dmx_release(&dec->demux);
 	if (dec->fe) {
 		dvb_unregister_frontend(dec->fe);
-		if (dec->fe->ops.release)
-			dec->fe->ops.release(dec->fe);
+		dvb_frontend_detach(dec->fe);
 	}
 	dvb_unregister_adapter(&dec->adapter);
 }
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH AUTOSEL 4.14 11/20] media: dvb-core: Fix kernel WARNING for blocking operation in wait_event*()
       [not found] <20230525184520.2004878-1-sashal@kernel.org>
                   ` (7 preceding siblings ...)
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 10/20] media: ttusb-dec: fix memory leak in ttusb_dec_exit_dvb() Sasha Levin
@ 2023-05-25 18:45 ` Sasha Levin
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 12/20] media: dvb-core: Fix use-after-free due to race condition at dvb_ca_en50221 Sasha Levin
  9 siblings, 0 replies; 11+ messages in thread
From: Sasha Levin @ 2023-05-25 18:45 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Takashi Iwai, Yu Hao, Mauro Carvalho Chehab, Sasha Levin,
	robert_s, chenzhongjin, linma, imv4bel, linux-media

From: Takashi Iwai <tiwai@suse.de>

[ Upstream commit b8c75e4a1b325ea0a9433fa8834be97b5836b946 ]

Using a semaphore in the wait_event*() condition is no good idea.
It hits a kernel WARN_ON() at prepare_to_wait_event() like:
  do not call blocking ops when !TASK_RUNNING; state=1 set at
  prepare_to_wait_event+0x6d/0x690

For avoiding the potential deadlock, rewrite to an open-coded loop
instead.  Unlike the loop in wait_event*(), this uses wait_woken()
after the condition check, hence the task state stays consistent.

CVE-2023-31084 was assigned to this bug.

Link: https://lore.kernel.org/r/CA+UBctCu7fXn4q41O_3=id1+OdyQ85tZY1x+TkT-6OVBL6KAUw@mail.gmail.com/

Link: https://lore.kernel.org/linux-media/20230512151800.1874-1-tiwai@suse.de
Reported-by: Yu Hao <yhao016@ucr.edu>
Closes: https://nvd.nist.gov/vuln/detail/CVE-2023-31084
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/media/dvb-core/dvb_frontend.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index e3a4a4688c2ec..651234584eb2c 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -301,14 +301,22 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe,
 	}
 
 	if (events->eventw == events->eventr) {
-		int ret;
+		struct wait_queue_entry wait;
+		int ret = 0;
 
 		if (flags & O_NONBLOCK)
 			return -EWOULDBLOCK;
 
-		ret = wait_event_interruptible(events->wait_queue,
-					       dvb_frontend_test_event(fepriv, events));
-
+		init_waitqueue_entry(&wait, current);
+		add_wait_queue(&events->wait_queue, &wait);
+		while (!dvb_frontend_test_event(fepriv, events)) {
+			wait_woken(&wait, TASK_INTERRUPTIBLE, 0);
+			if (signal_pending(current)) {
+				ret = -ERESTARTSYS;
+				break;
+			}
+		}
+		remove_wait_queue(&events->wait_queue, &wait);
 		if (ret < 0)
 			return ret;
 	}
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH AUTOSEL 4.14 12/20] media: dvb-core: Fix use-after-free due to race condition at dvb_ca_en50221
       [not found] <20230525184520.2004878-1-sashal@kernel.org>
                   ` (8 preceding siblings ...)
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 11/20] media: dvb-core: Fix kernel WARNING for blocking operation in wait_event*() Sasha Levin
@ 2023-05-25 18:45 ` Sasha Levin
  9 siblings, 0 replies; 11+ messages in thread
From: Sasha Levin @ 2023-05-25 18:45 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Hyunwoo Kim, Mauro Carvalho Chehab, Sasha Levin, yongsuyoo0215,
	linma, linux-media

From: Hyunwoo Kim <v4bel@theori.io>

[ Upstream commit 280a8ab81733da8bc442253c700a52c4c0886ffd ]

If the device node of dvb_ca_en50221 is open() and the
device is disconnected, a UAF may occur when calling
close() on the device node.

The root cause is that wake_up() and wait_event() for
dvbdev->wait_queue are not implemented.

So implement wait_event() function in dvb_ca_en50221_release()
and add 'remove_mutex' which prevents race condition
for 'ca->exit'.

[mchehab: fix a checkpatch warning]

Link: https://lore.kernel.org/linux-media/20221121063308.GA33821@ubuntu
Signed-off-by: Hyunwoo Kim <v4bel@theori.io>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/media/dvb-core/dvb_ca_en50221.c | 37 ++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
index 56114d85510f5..5dc8b2d143520 100644
--- a/drivers/media/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb-core/dvb_ca_en50221.c
@@ -161,6 +161,12 @@ struct dvb_ca_private {
 
 	/* mutex serializing ioctls */
 	struct mutex ioctl_mutex;
+
+	/* A mutex used when a device is disconnected */
+	struct mutex remove_mutex;
+
+	/* Whether the device is disconnected */
+	int exit;
 };
 
 static void dvb_ca_private_free(struct dvb_ca_private *ca)
@@ -1713,12 +1719,22 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
 
 	dprintk("%s\n", __func__);
 
-	if (!try_module_get(ca->pub->owner))
+	mutex_lock(&ca->remove_mutex);
+
+	if (ca->exit) {
+		mutex_unlock(&ca->remove_mutex);
+		return -ENODEV;
+	}
+
+	if (!try_module_get(ca->pub->owner)) {
+		mutex_unlock(&ca->remove_mutex);
 		return -EIO;
+	}
 
 	err = dvb_generic_open(inode, file);
 	if (err < 0) {
 		module_put(ca->pub->owner);
+		mutex_unlock(&ca->remove_mutex);
 		return err;
 	}
 
@@ -1743,6 +1759,7 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
 
 	dvb_ca_private_get(ca);
 
+	mutex_unlock(&ca->remove_mutex);
 	return 0;
 }
 
@@ -1762,6 +1779,8 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
 
 	dprintk("%s\n", __func__);
 
+	mutex_lock(&ca->remove_mutex);
+
 	/* mark the CA device as closed */
 	ca->open = 0;
 	dvb_ca_en50221_thread_update_delay(ca);
@@ -1772,6 +1791,13 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
 
 	dvb_ca_private_put(ca);
 
+	if (dvbdev->users == 1 && ca->exit == 1) {
+		mutex_unlock(&ca->remove_mutex);
+		wake_up(&dvbdev->wait_queue);
+	} else {
+		mutex_unlock(&ca->remove_mutex);
+	}
+
 	return err;
 }
 
@@ -1896,6 +1922,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
 	}
 
 	mutex_init(&ca->ioctl_mutex);
+	mutex_init(&ca->remove_mutex);
 
 	if (signal_pending(current)) {
 		ret = -EINTR;
@@ -1939,6 +1966,14 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
 
 	dprintk("%s\n", __func__);
 
+	mutex_lock(&ca->remove_mutex);
+	ca->exit = 1;
+	mutex_unlock(&ca->remove_mutex);
+
+	if (ca->dvbdev->users < 1)
+		wait_event(ca->dvbdev->wait_queue,
+				ca->dvbdev->users == 1);
+
 	/* shutdown the thread if there was one */
 	kthread_stop(ca->thread);
 
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH AUTOSEL 4.14 09/20] media: netup_unidvb: fix irq init by register it at the end of probe
  2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 09/20] media: netup_unidvb: fix irq init by register it at the end of probe Sasha Levin
@ 2023-06-16 19:20   ` Pavel Machek
  0 siblings, 0 replies; 11+ messages in thread
From: Pavel Machek @ 2023-06-16 19:20 UTC (permalink / raw)
  To: Sasha Levin
  Cc: linux-kernel, stable, Wei Chen, Mauro Carvalho Chehab, serjk,
	aospan, linux-media

[-- Attachment #1: Type: text/plain, Size: 1503 bytes --]

Hi!

> [ Upstream commit e6ad6233592593079db5c8fa592c298e51bc1356 ]
> 
> IRQ handler netup_spi_interrupt() takes spinlock spi->lock. The lock
> is initialized in netup_spi_init(). However, irq handler is registered
> before initializing the lock.
> 
> Spinlock dma->lock and i2c->lock suffer from the same problem.
> 
> Fix this by registering the irq at the end of probe.

Are you sure you got the error handling right? AFAICT
netup_unidvb_dma_fini(ndev, 0/1); is needed here.

Best regards,
								Pavel

> +++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
> @@ -943,6 +938,14 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev,
>  		dev_err(&pci_dev->dev, "netup_unidvb: DMA setup failed\n");
>  		goto dma_setup_err;
>  	}
> +
> +	if (request_irq(pci_dev->irq, netup_unidvb_isr, IRQF_SHARED,
> +			"netup_unidvb", pci_dev) < 0) {
> +		dev_err(&pci_dev->dev,
> +			"%s(): can't get IRQ %d\n", __func__, pci_dev->irq);
> +		goto dma_setup_err;
> +	}
> +
>  	dev_info(&pci_dev->dev,
>  		"netup_unidvb: device has been initialized\n");
>  	return 0;
> @@ -961,8 +964,6 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev,
>  	dma_free_coherent(&pci_dev->dev, ndev->dma_size,
>  			ndev->dma_virt, ndev->dma_phys);
>  dma_alloc_err:
> -	free_irq(pci_dev->irq, pci_dev);
> -irq_request_err:
>  	iounmap(ndev->lmmio1);
>  pci_bar1_error:
>  	iounmap(ndev->lmmio0);

-- 
People of Russia, stop Putin before his war on Ukraine escalates.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2023-06-16 19:35 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20230525184520.2004878-1-sashal@kernel.org>
2023-05-25 18:44 ` [PATCH AUTOSEL 4.14 03/20] media: dvb-usb: az6027: fix three null-ptr-deref in az6027_i2c_xfer() Sasha Levin
2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 04/20] media: dvb-usb-v2: ec168: fix null-ptr-deref in ec168_i2c_xfer() Sasha Levin
2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 05/20] media: dvb-usb-v2: ce6230: fix null-ptr-deref in ce6230_i2c_master_xfer() Sasha Levin
2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 06/20] media: dvb-usb-v2: rtl28xxu: fix null-ptr-deref in rtl28xxu_i2c_xfer Sasha Levin
2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 07/20] media: dvb-usb: digitv: fix null-ptr-deref in digitv_i2c_xfer() Sasha Levin
2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 08/20] media: dvb-usb: dw2102: fix uninit-value in su3000_read_mac_address Sasha Levin
2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 09/20] media: netup_unidvb: fix irq init by register it at the end of probe Sasha Levin
2023-06-16 19:20   ` Pavel Machek
2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 10/20] media: ttusb-dec: fix memory leak in ttusb_dec_exit_dvb() Sasha Levin
2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 11/20] media: dvb-core: Fix kernel WARNING for blocking operation in wait_event*() Sasha Levin
2023-05-25 18:45 ` [PATCH AUTOSEL 4.14 12/20] media: dvb-core: Fix use-after-free due to race condition at dvb_ca_en50221 Sasha Levin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).