packages: kernel/kernel-regressions.patch - one more regression fix: http:/...

pluto pluto at pld-linux.org
Wed Sep 16 10:01:44 CEST 2009


Author: pluto                        Date: Wed Sep 16 08:01:44 2009 GMT
Module: packages                      Tag: HEAD
---- Log message:
- one more regression fix: http://patchwork.kernel.org/patch/45707.

---- Files affected:
packages/kernel:
   kernel-regressions.patch (1.3 -> 1.4) 

---- Diffs:

================================================================
Index: packages/kernel/kernel-regressions.patch
diff -u packages/kernel/kernel-regressions.patch:1.3 packages/kernel/kernel-regressions.patch:1.4
--- packages/kernel/kernel-regressions.patch:1.3	Tue Mar 31 14:02:35 2009
+++ packages/kernel/kernel-regressions.patch	Wed Sep 16 10:01:38 2009
@@ -108,3 +108,239 @@
  }
  
  void __init rpc_init_generic_auth(void)
+From d238e150805a0710fa626f9a7f65816aa15b741c Mon Sep 17 00:00:00 2001
+From: Brian Rogers <brian at xyzw.org>
+Date: Fri, 4 Sep 2009 05:55:01 -0700
+Subject: [PATCH] Fix memory corruption during IR initialization for various tuner cards
+
+In two different places the IR_i2c_init_data structure is used to store some
+data for particular cards that will later override the settings that would
+otherwise be used by the ir-kbd-i2c driver in ir_probe(). The way those
+settings get there is problematic: init_data is on the stack, and a pointer to
+it is stored to be used after the function that sets it up returns. Not good.
+
+init_data might be overwritten by the time ir_probe() runs. ir_probe() will
+then call ir_input_init(), which proceeds to fill out the dev->keybit bit
+array with a 1 in the appropriate slot for every key on the tuner's remote.
+
+But if the keymap pointer now points to random garbage, that will be used
+instead to determine where to write each 1. And since IR_KEYTAB_TYPE is u32,
+it can be write millions of bits past the end of dev->keybit. Essentially
+this bug writes a 1 to up to 128 random bits in memory, stopping early (and
+oopsing) if or when it hits an invalid page.
+
+To fix this, I define a static IR_i2c_init_data struct for each card that
+needs one rather than creating the data on the stack. This way, I can supply a
+pointer that will remain valid. Also I don't have to allocate memory just to
+store information that's already known at compile time and I don't have bother
+freeing it, either.
+
+This fixes a regression caused by commit 4d7a2d6721.
+
+Signed-off-by: Brian Rogers <brian at xyzw.org>
+---
+ drivers/media/video/em28xx/em28xx-cards.c   |   36 +++++++++-----
+ drivers/media/video/saa7134/saa7134-input.c |   71 ++++++++++++++++++---------
+ 2 files changed, 70 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
+index 1c2e544..be9a4e8 100644
+--- a/drivers/media/video/em28xx/em28xx-cards.c
++++ b/drivers/media/video/em28xx/em28xx-cards.c
+@@ -2167,11 +2167,29 @@ static int em28xx_hint_board(struct em28xx *dev)
+ 	return -1;
+ }
+ 
++static struct IR_i2c_init_data init_data_em28xx_terratec = {
++	.name = "i2c IR (EM28XX Terratec)",
++	.ir_codes = ir_codes_em_terratec,
++	.get_key = em28xx_get_key_terratec,
++};
++
++static struct IR_i2c_init_data init_data_em28xx_pinnacle = {
++	.name = "i2c IR (EM28XX Pinnacle PCTV)",
++	.ir_codes = ir_codes_pinnacle_grey,
++	.get_key = em28xx_get_key_pinnacle_usb_grey,
++};
++
++static struct IR_i2c_init_data init_data_em28xx_hauppauge = {
++	.name = "i2c IR (EM2840 Hauppauge)",
++	.ir_codes = ir_codes_hauppauge_new,
++	.get_key = em28xx_get_key_em_haup,
++};
++
+ /* ----------------------------------------------------------------------- */
+ void em28xx_register_i2c_ir(struct em28xx *dev)
+ {
+ 	struct i2c_board_info info;
+-	struct IR_i2c_init_data init_data;
++	struct IR_i2c_init_data *init_data = NULL;
+ 	const unsigned short addr_list[] = {
+ 		 0x30, 0x47, I2C_CLIENT_END
+ 	};
+@@ -2180,7 +2198,6 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
+ 		return;
+ 
+ 	memset(&info, 0, sizeof(struct i2c_board_info));
+-	memset(&init_data, 0, sizeof(struct IR_i2c_init_data));
+ 	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ 
+ 	/* detect & configure */
+@@ -2191,19 +2208,13 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
+ 		break;
+ 	case (EM2800_BOARD_TERRATEC_CINERGY_200):
+ 	case (EM2820_BOARD_TERRATEC_CINERGY_250):
+-		init_data.ir_codes = ir_codes_em_terratec;
+-		init_data.get_key = em28xx_get_key_terratec;
+-		init_data.name = "i2c IR (EM28XX Terratec)";
++		init_data = &init_data_em28xx_terratec;
+ 		break;
+ 	case (EM2820_BOARD_PINNACLE_USB_2):
+-		init_data.ir_codes = ir_codes_pinnacle_grey;
+-		init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
+-		init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
++		init_data = &init_data_em28xx_pinnacle;
+ 		break;
+ 	case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
+-		init_data.ir_codes = ir_codes_hauppauge_new;
+-		init_data.get_key = em28xx_get_key_em_haup;
+-		init_data.name = "i2c IR (EM2840 Hauppauge)";
++		init_data = &init_data_em28xx_hauppauge;
+ 		break;
+ 	case (EM2820_BOARD_MSI_VOX_USB_2):
+ 		break;
+@@ -2215,8 +2226,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
+ 		break;
+ 	}
+ 
+-	if (init_data.name)
+-		info.platform_data = &init_data;
++	info.platform_data = init_data;
+ 	i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
+ }
+ 
+diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
+index 6e219c2..bb17bb9 100644
+--- a/drivers/media/video/saa7134/saa7134-input.c
++++ b/drivers/media/video/saa7134/saa7134-input.c
+@@ -682,10 +682,46 @@ void saa7134_input_fini(struct saa7134_dev *dev)
+ 	dev->remote = NULL;
+ }
+ 
++static struct IR_i2c_init_data init_data_pinnacle_color = {
++	.name = "Pinnacle PCTV",
++	.get_key = get_key_pinnacle_color,
++	.ir_codes = ir_codes_pinnacle_color,
++};
++
++static struct IR_i2c_init_data init_data_pinnacle_grey = {
++	.name = "Pinnacle PCTV",
++	.get_key = get_key_pinnacle_grey,
++	.ir_codes = ir_codes_pinnacle_grey,
++};
++
++static struct IR_i2c_init_data init_data_purpletv = {
++	.name = "Purple TV",
++	.get_key = get_key_purpletv,
++	.ir_codes = ir_codes_purpletv,
++};
++
++static struct IR_i2c_init_data init_data_msi_tvanywhere_plus = {
++	.name = "MSI TV at nywhere Plus",
++	.get_key = get_key_msi_tvanywhere_plus,
++	.ir_codes = ir_codes_msi_tvanywhere_plus,
++};
++
++static struct IR_i2c_init_data init_data_hauppauge = {
++	.name = "HVR 1110",
++	.get_key = get_key_hvr1110,
++	.ir_codes = ir_codes_hauppauge_new,
++};
++
++static struct IR_i2c_init_data init_data_behold = {
++	.name = "BeholdTV",
++	.get_key = get_key_beholdm6xx,
++	.ir_codes = ir_codes_behold,
++};
++
+ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
+ {
+ 	struct i2c_board_info info;
+-	struct IR_i2c_init_data init_data;
++	struct IR_i2c_init_data *init_data = NULL;
+ 	const unsigned short addr_list[] = {
+ 		0x7a, 0x47, 0x71, 0x2d,
+ 		I2C_CLIENT_END
+@@ -706,30 +742,22 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
+ 	}
+ 
+ 	memset(&info, 0, sizeof(struct i2c_board_info));
+-	memset(&init_data, 0, sizeof(struct IR_i2c_init_data));
+ 	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ 
+ 	switch (dev->board) {
+ 	case SAA7134_BOARD_PINNACLE_PCTV_110i:
+ 	case SAA7134_BOARD_PINNACLE_PCTV_310i:
+-		init_data.name = "Pinnacle PCTV";
+-		if (pinnacle_remote == 0) {
+-			init_data.get_key = get_key_pinnacle_color;
+-			init_data.ir_codes = ir_codes_pinnacle_color;
+-		} else {
+-			init_data.get_key = get_key_pinnacle_grey;
+-			init_data.ir_codes = ir_codes_pinnacle_grey;
+-		}
++		if (pinnacle_remote == 0)
++			init_data = &init_data_pinnacle_color;
++		else
++			init_data = &init_data_pinnacle_grey;
++		info.addr = 0x47;
+ 		break;
+ 	case SAA7134_BOARD_UPMOST_PURPLE_TV:
+-		init_data.name = "Purple TV";
+-		init_data.get_key = get_key_purpletv;
+-		init_data.ir_codes = ir_codes_purpletv;
++		init_data = &init_data_purpletv;
+ 		break;
+ 	case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
+-		init_data.name = "MSI TV at nywhere Plus";
+-		init_data.get_key = get_key_msi_tvanywhere_plus;
+-		init_data.ir_codes = ir_codes_msi_tvanywhere_plus;
++		init_data = &init_data_msi_tvanywhere_plus;
+ 		info.addr = 0x30;
+ 		/* MSI TV at nywhere Plus controller doesn't seem to
+ 		   respond to probes unless we read something from
+@@ -741,9 +769,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
+ 			(1 == rc) ? "yes" : "no");
+ 		break;
+ 	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
+-		init_data.name = "HVR 1110";
+-		init_data.get_key = get_key_hvr1110;
+-		init_data.ir_codes = ir_codes_hauppauge_new;
++		init_data = &init_data_hauppauge;
+ 		break;
+ 	case SAA7134_BOARD_BEHOLD_607FM_MK3:
+ 	case SAA7134_BOARD_BEHOLD_607FM_MK5:
+@@ -757,9 +783,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
+ 	case SAA7134_BOARD_BEHOLD_M63:
+ 	case SAA7134_BOARD_BEHOLD_M6_EXTRA:
+ 	case SAA7134_BOARD_BEHOLD_H6:
+-		init_data.name = "BeholdTV";
+-		init_data.get_key = get_key_beholdm6xx;
+-		init_data.ir_codes = ir_codes_behold;
++		init_data = &init_data_behold;
+ 		break;
+ 	case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
+ 	case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+@@ -767,8 +791,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
+ 		break;
+ 	}
+ 
+-	if (init_data.name)
+-		info.platform_data = &init_data;
++	info.platform_data = init_data;
+ 	/* No need to probe if address is known */
+ 	if (info.addr) {
+ 		i2c_new_device(&dev->i2c_adap, &info);
+-- 
+1.6.3.3
+
================================================================

---- CVS-web:
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/packages/kernel/kernel-regressions.patch?r1=1.3&r2=1.4&f=u



More information about the pld-cvs-commit mailing list