Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1715023 > unrolled thread

[PATCH 3.16 063/134] [media] dw2102: limit messages to buffer size

Started byBen Hutchings <ben@decadent.org.uk>
First post2017-08-18 15:50 +0200
Last post2017-08-18 15:50 +0200
Articles 1 — 1 participant

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH 3.16 063/134] [media] dw2102: limit messages to buffer size Ben Hutchings <ben@decadent.org.uk> - 2017-08-18 15:50 +0200

#1715023 — [PATCH 3.16 063/134] [media] dw2102: limit messages to buffer size

FromBen Hutchings <ben@decadent.org.uk>
Date2017-08-18 15:50 +0200
Subject[PATCH 3.16 063/134] [media] dw2102: limit messages to buffer size
Message-ID<ufPOW-4q2-7@gated-at.bofh.it>
3.16.47-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Alyssa Milburn <amilburn@zall.org>

commit 950e252cb469f323740d78e4907843acef89eedb upstream.

Otherwise the i2c transfer functions can read or write beyond the end of
stack or heap buffers.

Signed-off-by: Alyssa Milburn <amilburn@zall.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
[bwh: Backported to 3.16:
 - Use obuf instead of state->data
 - Adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 drivers/media/usb/dvb-usb/dw2102.c | 54 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -247,6 +247,20 @@ static int dw2102_serit_i2c_transfer(str
 
 	switch (num) {
 	case 2:
+		if (msg[0].len != 1) {
+			warn("i2c rd: len=%d is not 1!\n",
+			     msg[0].len);
+			num = -EOPNOTSUPP;
+			break;
+		}
+
+		if (2 + msg[1].len > sizeof(buf6)) {
+			warn("i2c rd: len=%d is too big!\n",
+			     msg[1].len);
+			num = -EOPNOTSUPP;
+			break;
+		}
+
 		/* read si2109 register by number */
 		buf6[0] = msg[0].addr << 1;
 		buf6[1] = msg[0].len;
@@ -262,6 +276,13 @@ static int dw2102_serit_i2c_transfer(str
 	case 1:
 		switch (msg[0].addr) {
 		case 0x68:
+			if (2 + msg[0].len > sizeof(buf6)) {
+				warn("i2c wr: len=%d is too big!\n",
+				     msg[0].len);
+				num = -EOPNOTSUPP;
+				break;
+			}
+
 			/* write to si2109 register */
 			buf6[0] = msg[0].addr << 1;
 			buf6[1] = msg[0].len;
@@ -305,6 +326,13 @@ static int dw2102_earda_i2c_transfer(str
 		/* first write first register number */
 		u8 ibuf[MAX_XFER_SIZE], obuf[3];
 
+		if (2 + msg[0].len != sizeof(obuf)) {
+			warn("i2c rd: len=%d is not 1!\n",
+			     msg[0].len);
+			ret = -EOPNOTSUPP;
+			goto unlock;
+		}
+
 		if (2 + msg[1].len > sizeof(ibuf)) {
 			warn("i2c rd: len=%d is too big!\n",
 			     msg[1].len);
@@ -505,6 +533,12 @@ static int dw3101_i2c_transfer(struct i2
 		/* first write first register number */
 		u8 ibuf[MAX_XFER_SIZE], obuf[3];
 
+		if (2 + msg[0].len != sizeof(obuf)) {
+			warn("i2c rd: len=%d is not 1!\n",
+			     msg[0].len);
+			ret = -EOPNOTSUPP;
+			goto unlock;
+		}
 		if (2 + msg[1].len > sizeof(ibuf)) {
 			warn("i2c rd: len=%d is too big!\n",
 			     msg[1].len);
@@ -730,6 +764,13 @@ static int su3000_i2c_transfer(struct i2
 			msg[0].buf[0] = ibuf[1];
 			break;
 		default:
+			if (3 + msg[0].len > sizeof(obuf)) {
+				warn("i2c wr: len=%d is too big!\n",
+				     msg[0].len);
+				num = -EOPNOTSUPP;
+				break;
+			}
+
 			/* always i2c write*/
 			obuf[0] = 0x08;
 			obuf[1] = msg[0].addr;
@@ -745,6 +786,19 @@ static int su3000_i2c_transfer(struct i2
 		break;
 	case 2:
 		/* always i2c read */
+		if (4 + msg[0].len > sizeof(obuf)) {
+			warn("i2c rd: len=%d is too big!\n",
+			     msg[0].len);
+			num = -EOPNOTSUPP;
+			break;
+		}
+		if (1 + msg[1].len > sizeof(obuf)) {
+			warn("i2c rd: len=%d is too big!\n",
+			     msg[1].len);
+			num = -EOPNOTSUPP;
+			break;
+		}
+
 		obuf[0] = 0x09;
 		obuf[1] = msg[0].len;
 		obuf[2] = msg[1].len;

[toc] | [standalone]


Back to top | Article view | linux.kernel


csiph-web