Skip to contentSkip to conversation

cx18: introduce a helper function to avoid array overrun

PATCH In review Ethan Zhao 3 participants 3 messages Jan 6, 2014 – Jan 11, 2014

Subsystems (2)
lore
Share & tools
lore

Ethan Zhao

author
#0 lore raw

PATCH 1/1 cx18: introduce a helper function to avoid array overrun

cx18_i2c_register() is called in cx18_init_subdevs() with index greater than length of hw_bus array, that will cause array overrun, introduce a helper cx18_get_max_bus_num() to avoid it.

V2: fix a typo and use ARRAY_SIZE macro

---
 drivers/media/pci/cx18/cx18-driver.c | 2 +-
 drivers/media/pci/cx18/cx18-i2c.c    | 5 +++++
 drivers/media/pci/cx18/cx18-i2c.h    | 1 +
 3 files changed, 7 insertions(+), 1 deletion(-)
drivers/media/pci/cx18/cx18-driver.c +1 -1
index 6386ced..dadcd4a 100644
@@ -856,7 +856,7 @@ static void cx18_init_subdevs(struct cx18 *cx)
 	u32 device;
 	int i;
 
-	for (i = 0, device = 1; i < 32; i++, device <<= 1) {
+	for (i = 0, device = 1; i < cx18_get_max_bus_num(); i++, device <<= 1) {
 
 		if (!(device & hw))
 			continue;
drivers/media/pci/cx18/cx18-i2c.c +5 -0
index 4af8cd6..1a7b49b 100644
@@ -108,6 +108,11 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
 	       -1 : 0;
 }
 
+int cx18_get_max_bus_num(void)
+{
+	return ARRAY_SIZE(hw_bus);
+}
+
 int cx18_i2c_register(struct cx18 *cx, unsigned idx)
 {
 	struct v4l2_subdev *sd;
drivers/media/pci/cx18/cx18-i2c.h +1 -0
index 1180fdc..6f2ceb5 100644
@@ -21,6 +21,7 @@
  *  02111-1307  USA
  */
 
+int cx18_get_max_bus_num(void);
 int cx18_i2c_register(struct cx18 *cx, unsigned idx);
 struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw);
 
Signature · 1 line
1.8.3.4 (Apple Git-47)
#1 lore raw

Also CC to linux-media and Andy Walls who maintains this driver.

Regards,

Hans

Quoted 55 lines · Ethan Zhao

cx18_i2c_register() is called in cx18_init_subdevs() with index greater than length of hw_bus array, that will cause array overrun, introduce a helper cx18_get_max_bus_num() to avoid it.

V2: fix a typo and use ARRAY_SIZE macro

---
 drivers/media/pci/cx18/cx18-driver.c | 2 +-
 drivers/media/pci/cx18/cx18-i2c.c    | 5 +++++
 drivers/media/pci/cx18/cx18-i2c.h    | 1 +
 3 files changed, 7 insertions(+), 1 deletion(-)
drivers/media/pci/cx18/cx18-driver.c +1 -1
index 6386ced..dadcd4a 100644
@@ -856,7 +856,7 @@ static void cx18_init_subdevs(struct cx18 *cx)
 	u32 device;
 	int i;
 
-	for (i = 0, device = 1; i < 32; i++, device <<= 1) {
+	for (i = 0, device = 1; i < cx18_get_max_bus_num(); i++, device <<= 1) {
 
 		if (!(device & hw))
 			continue;
drivers/media/pci/cx18/cx18-i2c.c +5 -0
index 4af8cd6..1a7b49b 100644
@@ -108,6 +108,11 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
 	       -1 : 0;
 }
 
+int cx18_get_max_bus_num(void)
+{
+	return ARRAY_SIZE(hw_bus);
+}
+
 int cx18_i2c_register(struct cx18 *cx, unsigned idx)
 {
 	struct v4l2_subdev *sd;
drivers/media/pci/cx18/cx18-i2c.h +1 -0
index 1180fdc..6f2ceb5 100644
@@ -21,6 +21,7 @@
  *  02111-1307  USA
  */
 
+int cx18_get_max_bus_num(void);
 int cx18_i2c_register(struct cx18 *cx, unsigned idx);
 struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw);
 
maintainer
#2 lore raw
Quoted 14 lines · Hans Verkuil

Also CC to linux-media and Andy Walls who maintains this driver.

Regards,

Hans

Quoted 7 lines · Ethan Zhao

cx18_i2c_register() is called in cx18_init_subdevs() with index greater than length of hw_bus array, that will cause array overrun, introduce a helper cx18_get_max_bus_num() to avoid it.

V2: fix a typo and use ARRAY_SIZE macro

Hi Ethan,

There is no need for this change. See below.

Quoted 14 lines
Quoted 14 lines
---
 drivers/media/pci/cx18/cx18-driver.c | 2 +-
 drivers/media/pci/cx18/cx18-i2c.c    | 5 +++++
 drivers/media/pci/cx18/cx18-i2c.h    | 1 +
 3 files changed, 7 insertions(+), 1 deletion(-)
drivers/media/pci/cx18/cx18-driver.c +0 -0
index 6386ced..dadcd4a 100644
@@ -856,7 +856,7 @@ static void cx18_init_subdevs(struct cx18 *cx)
 	u32 device;
 	int i;
 
Quoted 5 lines

drivers/media/pci/cx18/cx18-driver.c static void cx18_init_subdevs(struct cx18 *cx) · line 862

Quoted 5 lines
drivers/media/pci/cx18/cx18-driver.c +1 -1
-	for (i = 0, device = 1; i < 32; i++, device <<= 1) {
+	for (i = 0, device = 1; i < cx18_get_max_bus_num(); i++, device <<= 1) {
 
 		if (!(device & hw))
 			continue;

This check of "!(device & hw)" already does the bounds check. Card specific, I2C device presence flags are statically compiled into the driver in cx18-cards.c and are used in this check.

The ivtv driver does the same sort of check in
ivtv-driver.c:ivtv_load_and_init_modules().

Both the cx18 and ivtv drivers are very mature, so I don't want any unecessary code churn in them to address non-problems.

Regards,
Andy

Quoted 29 lines
Quoted 29 lines
drivers/media/pci/cx18/cx18-i2c.c +5 -0
index 4af8cd6..1a7b49b 100644
@@ -108,6 +108,11 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
 	       -1 : 0;
 }
 
+int cx18_get_max_bus_num(void)
+{
+	return ARRAY_SIZE(hw_bus);
+}
+
 int cx18_i2c_register(struct cx18 *cx, unsigned idx)
 {
 	struct v4l2_subdev *sd;
drivers/media/pci/cx18/cx18-i2c.h +1 -0
index 1180fdc..6f2ceb5 100644
@@ -21,6 +21,7 @@
  *  02111-1307  USA
  */
 
+int cx18_get_max_bus_num(void);
 int cx18_i2c_register(struct cx18 *cx, unsigned idx);
 struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw);