]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.16.17/pci-correctly-allocate-return-buffers-for-osc-calls.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.16.17 / pci-correctly-allocate-return-buffers-for-osc-calls.patch
CommitLineData
cbf3caa5
GKH
1From owner-linux-pci@atrey.karlin.mff.cuni.cz Wed May 17 11:04:37 2006
2Subject: PCI: correctly allocate return buffers for osc calls
3From: Kristen Accardi <kristen.c.accardi@intel.com>
4To: linux-pci@atrey.karlin.mff.cuni.cz
5Cc: linux-kernel@vger.kernel.org, greg@kroah.com
6Date: Wed, 17 May 2006 11:13:37 -0700
7Message-Id: <1147889618.8472.6.camel@whizzy>
8
9The OSC set and query functions do not allocate enough space for return values,
10and set the output buffer length to a false, too large value. This causes the
11acpi-ca code to assume that the output buffer is larger than it actually is,
12and overwrite memory when copying acpi return buffers into this caller provided
13buffer. In some cases this can cause kernel oops if the memory that is
14overwritten is a pointer. This patch will change these calls to use a
15dynamically allocated output buffer, thus allowing the acpi-ca code to decide
16how much space is needed.
17
18Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
19Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
70a83a42 20Signed-off-by: Chris Wright <chrisw@sous-sol.org>
cbf3caa5
GKH
21
22---
23 drivers/pci/pci-acpi.c | 60 ++++++++++++++++++++++++++++---------------------
24 1 file changed, 35 insertions(+), 25 deletions(-)
25
26--- linux-2.6.16.16.orig/drivers/pci/pci-acpi.c
27+++ linux-2.6.16.16/drivers/pci/pci-acpi.c
28@@ -33,13 +33,10 @@ acpi_query_osc (
29 acpi_status status;
30 struct acpi_object_list input;
31 union acpi_object in_params[4];
32- struct acpi_buffer output;
33- union acpi_object out_obj;
34+ struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
35+ union acpi_object *out_obj;
36 u32 osc_dw0;
37
38- /* Setting up output buffer */
39- output.length = sizeof(out_obj) + 3*sizeof(u32);
40- output.pointer = &out_obj;
41
42 /* Setting up input parameters */
43 input.count = 4;
44@@ -61,12 +58,15 @@ acpi_query_osc (
45 "Evaluate _OSC Set fails. Status = 0x%04x\n", status);
46 return status;
47 }
48- if (out_obj.type != ACPI_TYPE_BUFFER) {
49+ out_obj = output.pointer;
50+
51+ if (out_obj->type != ACPI_TYPE_BUFFER) {
52 printk(KERN_DEBUG
53 "Evaluate _OSC returns wrong type\n");
54- return AE_TYPE;
55+ status = AE_TYPE;
56+ goto query_osc_out;
57 }
58- osc_dw0 = *((u32 *) out_obj.buffer.pointer);
59+ osc_dw0 = *((u32 *) out_obj->buffer.pointer);
60 if (osc_dw0) {
61 if (osc_dw0 & OSC_REQUEST_ERROR)
62 printk(KERN_DEBUG "_OSC request fails\n");
63@@ -76,15 +76,21 @@ acpi_query_osc (
64 printk(KERN_DEBUG "_OSC invalid revision\n");
65 if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
66 /* Update Global Control Set */
67- global_ctrlsets = *((u32 *)(out_obj.buffer.pointer+8));
68- return AE_OK;
69+ global_ctrlsets = *((u32 *)(out_obj->buffer.pointer+8));
70+ status = AE_OK;
71+ goto query_osc_out;
72 }
73- return AE_ERROR;
74+ status = AE_ERROR;
75+ goto query_osc_out;
76 }
77
78 /* Update Global Control Set */
79- global_ctrlsets = *((u32 *)(out_obj.buffer.pointer + 8));
80- return AE_OK;
81+ global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8));
82+ status = AE_OK;
83+
84+query_osc_out:
85+ kfree(output.pointer);
86+ return status;
87 }
88
89
90@@ -96,14 +102,10 @@ acpi_run_osc (
91 acpi_status status;
92 struct acpi_object_list input;
93 union acpi_object in_params[4];
94- struct acpi_buffer output;
95- union acpi_object out_obj;
96+ struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
97+ union acpi_object *out_obj;
98 u32 osc_dw0;
99
100- /* Setting up output buffer */
101- output.length = sizeof(out_obj) + 3*sizeof(u32);
102- output.pointer = &out_obj;
103-
104 /* Setting up input parameters */
105 input.count = 4;
106 input.pointer = in_params;
107@@ -124,12 +126,14 @@ acpi_run_osc (
108 "Evaluate _OSC Set fails. Status = 0x%04x\n", status);
109 return status;
110 }
111- if (out_obj.type != ACPI_TYPE_BUFFER) {
112+ out_obj = output.pointer;
113+ if (out_obj->type != ACPI_TYPE_BUFFER) {
114 printk(KERN_DEBUG
115 "Evaluate _OSC returns wrong type\n");
116- return AE_TYPE;
117+ status = AE_TYPE;
118+ goto run_osc_out;
119 }
120- osc_dw0 = *((u32 *) out_obj.buffer.pointer);
121+ osc_dw0 = *((u32 *) out_obj->buffer.pointer);
122 if (osc_dw0) {
123 if (osc_dw0 & OSC_REQUEST_ERROR)
124 printk(KERN_DEBUG "_OSC request fails\n");
125@@ -139,11 +143,17 @@ acpi_run_osc (
126 printk(KERN_DEBUG "_OSC invalid revision\n");
127 if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
128 printk(KERN_DEBUG "_OSC FW not grant req. control\n");
129- return AE_SUPPORT;
130+ status = AE_SUPPORT;
131+ goto run_osc_out;
132 }
133- return AE_ERROR;
134+ status = AE_ERROR;
135+ goto run_osc_out;
136 }
137- return AE_OK;
138+ status = AE_OK;
139+
140+run_osc_out:
141+ kfree(output.pointer);
142+ return status;
143 }
144
145 /**