]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
add pciehp bugfix
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 17 May 2006 20:29:33 +0000 (13:29 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 17 May 2006 20:29:33 +0000 (13:29 -0700)
queue-2.6.16/pci-correctly-allocate-return-buffers-for-osc-calls.patch [new file with mode: 0644]
queue-2.6.16/series

diff --git a/queue-2.6.16/pci-correctly-allocate-return-buffers-for-osc-calls.patch b/queue-2.6.16/pci-correctly-allocate-return-buffers-for-osc-calls.patch
new file mode 100644 (file)
index 0000000..fad5e7c
--- /dev/null
@@ -0,0 +1,144 @@
+From owner-linux-pci@atrey.karlin.mff.cuni.cz Wed May 17 11:04:37 2006
+Subject: PCI: correctly allocate return buffers for osc calls
+From: Kristen Accardi <kristen.c.accardi@intel.com>
+To: linux-pci@atrey.karlin.mff.cuni.cz
+Cc: linux-kernel@vger.kernel.org, greg@kroah.com
+Date: Wed, 17 May 2006 11:13:37 -0700
+Message-Id: <1147889618.8472.6.camel@whizzy>
+
+The OSC set and query functions do not allocate enough space for return values,
+and set the output buffer length to a false, too large value.  This causes the 
+acpi-ca code to assume that the output buffer is larger than it actually is, 
+and overwrite memory when copying acpi return buffers into this caller provided
+buffer.  In some cases this can cause kernel oops if the memory that is 
+overwritten is a pointer.  This patch will change these calls to use a 
+dynamically allocated output buffer, thus allowing the acpi-ca code to decide 
+how much space is needed.
+
+Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/pci-acpi.c |   60 ++++++++++++++++++++++++++++---------------------
+ 1 file changed, 35 insertions(+), 25 deletions(-)
+
+--- linux-2.6.16.16.orig/drivers/pci/pci-acpi.c
++++ linux-2.6.16.16/drivers/pci/pci-acpi.c
+@@ -33,13 +33,10 @@ acpi_query_osc (
+       acpi_status             status;
+       struct acpi_object_list input;
+       union acpi_object       in_params[4];
+-      struct acpi_buffer      output;
+-      union acpi_object       out_obj;        
++      struct acpi_buffer      output = {ACPI_ALLOCATE_BUFFER, NULL};
++      union acpi_object       *out_obj;
+       u32                     osc_dw0;
+-      /* Setting up output buffer */
+-      output.length = sizeof(out_obj) + 3*sizeof(u32);  
+-      output.pointer = &out_obj;
+       
+       /* Setting up input parameters */
+       input.count = 4;
+@@ -61,12 +58,15 @@ acpi_query_osc (
+                       "Evaluate _OSC Set fails. Status = 0x%04x\n", status);
+               return status;
+       }
+-      if (out_obj.type != ACPI_TYPE_BUFFER) {
++      out_obj = output.pointer;
++
++      if (out_obj->type != ACPI_TYPE_BUFFER) {
+               printk(KERN_DEBUG  
+                       "Evaluate _OSC returns wrong type\n");
+-              return AE_TYPE;
++              status = AE_TYPE;
++              goto query_osc_out;
+       }
+-      osc_dw0 = *((u32 *) out_obj.buffer.pointer);
++      osc_dw0 = *((u32 *) out_obj->buffer.pointer);
+       if (osc_dw0) {
+               if (osc_dw0 & OSC_REQUEST_ERROR)
+                       printk(KERN_DEBUG "_OSC request fails\n"); 
+@@ -76,15 +76,21 @@ acpi_query_osc (
+                       printk(KERN_DEBUG "_OSC invalid revision\n"); 
+               if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
+                       /* Update Global Control Set */
+-                      global_ctrlsets = *((u32 *)(out_obj.buffer.pointer+8));
+-                      return AE_OK;
++                      global_ctrlsets = *((u32 *)(out_obj->buffer.pointer+8));
++                      status = AE_OK;
++                      goto query_osc_out;
+               }
+-              return AE_ERROR;
++              status = AE_ERROR;
++              goto query_osc_out;
+       }
+       /* Update Global Control Set */
+-      global_ctrlsets = *((u32 *)(out_obj.buffer.pointer + 8));
+-      return AE_OK;
++      global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8));
++      status = AE_OK;
++
++query_osc_out:
++      kfree(output.pointer);
++      return status;
+ }
+@@ -96,14 +102,10 @@ acpi_run_osc (
+       acpi_status             status;
+       struct acpi_object_list input;
+       union acpi_object       in_params[4];
+-      struct acpi_buffer      output;
+-      union acpi_object       out_obj;        
++      struct acpi_buffer      output = {ACPI_ALLOCATE_BUFFER, NULL};
++      union acpi_object       *out_obj;
+       u32                     osc_dw0;
+-      /* Setting up output buffer */
+-      output.length = sizeof(out_obj) + 3*sizeof(u32);  
+-      output.pointer = &out_obj;
+-      
+       /* Setting up input parameters */
+       input.count = 4;
+       input.pointer = in_params;
+@@ -124,12 +126,14 @@ acpi_run_osc (
+                       "Evaluate _OSC Set fails. Status = 0x%04x\n", status);
+               return status;
+       }
+-      if (out_obj.type != ACPI_TYPE_BUFFER) {
++      out_obj = output.pointer;
++      if (out_obj->type != ACPI_TYPE_BUFFER) {
+               printk(KERN_DEBUG  
+                       "Evaluate _OSC returns wrong type\n");
+-              return AE_TYPE;
++              status = AE_TYPE;
++              goto run_osc_out;
+       }
+-      osc_dw0 = *((u32 *) out_obj.buffer.pointer);
++      osc_dw0 = *((u32 *) out_obj->buffer.pointer);
+       if (osc_dw0) {
+               if (osc_dw0 & OSC_REQUEST_ERROR)
+                       printk(KERN_DEBUG "_OSC request fails\n"); 
+@@ -139,11 +143,17 @@ acpi_run_osc (
+                       printk(KERN_DEBUG "_OSC invalid revision\n"); 
+               if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
+                       printk(KERN_DEBUG "_OSC FW not grant req. control\n");
+-                      return AE_SUPPORT;
++                      status = AE_SUPPORT;
++                      goto run_osc_out;
+               }
+-              return AE_ERROR;
++              status = AE_ERROR;
++              goto run_osc_out;
+       }
+-      return AE_OK;
++      status = AE_OK;
++
++run_osc_out:
++      kfree(output.pointer);
++      return status;
+ }
+ /**
index 8df69f08e083e5272ea2d692f5f0dfea4e04a56c..83b6790ba0e00238f60a61e2d9a4e3e7d5388514 100644 (file)
@@ -9,3 +9,4 @@ scx200_acb-fix-resource-name-use-after-free.patch
 netfilter-do_add_counters-race-possible-info-leak.patch
 tg3-ethtool-always-report-port-is-tp.patch
 selinux-check-for-failed-kmalloc-in-security_sid_to_context.patch
+pci-correctly-allocate-return-buffers-for-osc-calls.patch