Commit a5f3ba60 authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] fixes from stack consumption audit

http://bugzilla.kernel.org/show_bug.cgi?id=2901Signed-off-by: default avatarLuming Yu <luming.yu@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 0da7309c
......@@ -126,8 +126,8 @@ acpi_pci_bind (
acpi_status status = AE_OK;
struct acpi_pci_data *data = NULL;
struct acpi_pci_data *pdata = NULL;
char pathname[ACPI_PATHNAME_MAX] = {0};
struct acpi_buffer buffer = {ACPI_PATHNAME_MAX, pathname};
char *pathname = NULL;
struct acpi_buffer buffer = {0, NULL};
acpi_handle handle = NULL;
ACPI_FUNCTION_TRACE("acpi_pci_bind");
......@@ -135,9 +135,18 @@ acpi_pci_bind (
if (!device || !device->parent)
return_VALUE(-EINVAL);
pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
if(!pathname)
return_VALUE(-ENOMEM);
memset(pathname, 0, ACPI_PATHNAME_MAX);
buffer.length = ACPI_PATHNAME_MAX;
buffer.pointer = pathname;
data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
if (!data)
if (!data){
kfree (pathname);
return_VALUE(-ENOMEM);
}
memset(data, 0, sizeof(struct acpi_pci_data));
acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
......@@ -253,6 +262,7 @@ acpi_pci_bind (
}
end:
kfree(pathname);
if (result)
kfree(data);
......@@ -269,17 +279,29 @@ acpi_pci_bind_root (
int result = 0;
acpi_status status = AE_OK;
struct acpi_pci_data *data = NULL;
char pathname[ACPI_PATHNAME_MAX] = {0};
struct acpi_buffer buffer = {ACPI_PATHNAME_MAX, pathname};
char *pathname = NULL;
struct acpi_buffer buffer = {0, NULL};
ACPI_FUNCTION_TRACE("acpi_pci_bind_root");
if (!device || !id || !bus)
pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
if(!pathname)
return_VALUE(-ENOMEM);
memset(pathname, 0, ACPI_PATHNAME_MAX);
buffer.length = sizeof(pathname);
buffer.pointer = pathname;
if (!device || !id || !bus){
kfree(pathname);
return_VALUE(-EINVAL);
}
data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
if (!data)
if (!data){
kfree(pathname);
return_VALUE(-ENOMEM);
}
memset(data, 0, sizeof(struct acpi_pci_data));
data->id = *id;
......@@ -301,6 +323,7 @@ acpi_pci_bind_root (
}
end:
kfree(pathname);
if (result != 0)
kfree(data);
......
......@@ -156,7 +156,7 @@ acpi_pci_irq_add_prt (
int bus)
{
acpi_status status = AE_OK;
char pathname[ACPI_PATHNAME_MAX] = {0};
char *pathname = NULL;
struct acpi_buffer buffer = {0, NULL};
struct acpi_pci_routing_table *prt = NULL;
struct acpi_pci_routing_table *entry = NULL;
......@@ -164,6 +164,11 @@ acpi_pci_irq_add_prt (
ACPI_FUNCTION_TRACE("acpi_pci_irq_add_prt");
pathname = (char *) kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
if(!pathname)
return_VALUE(-ENOMEM);
memset(pathname, 0, ACPI_PATHNAME_MAX);
if (first_time) {
acpi_prt.count = 0;
INIT_LIST_HEAD(&acpi_prt.entries);
......@@ -192,12 +197,15 @@ acpi_pci_irq_add_prt (
if (status != AE_BUFFER_OVERFLOW) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n",
acpi_format_exception(status)));
kfree(pathname);
return_VALUE(-ENODEV);
}
prt = kmalloc(buffer.length, GFP_KERNEL);
if (!prt)
if (!prt){
kfree(pathname);
return_VALUE(-ENOMEM);
}
memset(prt, 0, buffer.length);
buffer.pointer = prt;
......@@ -205,6 +213,7 @@ acpi_pci_irq_add_prt (
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n",
acpi_format_exception(status)));
kfree(pathname);
kfree(buffer.pointer);
return_VALUE(-ENODEV);
}
......@@ -217,6 +226,7 @@ acpi_pci_irq_add_prt (
((unsigned long) entry + entry->length);
}
kfree(pathname);
kfree(prt);
return_VALUE(0);
......
......@@ -307,50 +307,57 @@ acpi_pci_link_set (
struct {
struct acpi_resource res;
struct acpi_resource end;
} resource;
struct acpi_buffer buffer = {sizeof(resource)+1, &resource};
} *resource;
struct acpi_buffer buffer = {0, NULL};
ACPI_FUNCTION_TRACE("acpi_pci_link_set");
if (!link || !irq)
return_VALUE(-EINVAL);
memset(&resource, 0, sizeof(resource));
resource = kmalloc( sizeof(*resource)+1, GFP_KERNEL);
if(!resource)
return_VALUE(-ENOMEM);
memset(resource, 0, sizeof(*resource)+1);
buffer.length = sizeof(*resource) +1;
buffer.pointer = resource;
switch(link->irq.resource_type) {
case ACPI_RSTYPE_IRQ:
resource.res.id = ACPI_RSTYPE_IRQ;
resource.res.length = sizeof(struct acpi_resource);
resource.res.data.irq.edge_level = link->irq.edge_level;
resource.res.data.irq.active_high_low = link->irq.active_high_low;
resource->res.id = ACPI_RSTYPE_IRQ;
resource->res.length = sizeof(struct acpi_resource);
resource->res.data.irq.edge_level = link->irq.edge_level;
resource->res.data.irq.active_high_low = link->irq.active_high_low;
if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
resource.res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
resource->res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
else
resource.res.data.irq.shared_exclusive = ACPI_SHARED;
resource.res.data.irq.number_of_interrupts = 1;
resource.res.data.irq.interrupts[0] = irq;
resource->res.data.irq.shared_exclusive = ACPI_SHARED;
resource->res.data.irq.number_of_interrupts = 1;
resource->res.data.irq.interrupts[0] = irq;
break;
case ACPI_RSTYPE_EXT_IRQ:
resource.res.id = ACPI_RSTYPE_EXT_IRQ;
resource.res.length = sizeof(struct acpi_resource);
resource.res.data.extended_irq.producer_consumer = ACPI_CONSUMER;
resource.res.data.extended_irq.edge_level = link->irq.edge_level;
resource.res.data.extended_irq.active_high_low = link->irq.active_high_low;
resource->res.id = ACPI_RSTYPE_EXT_IRQ;
resource->res.length = sizeof(struct acpi_resource);
resource->res.data.extended_irq.producer_consumer = ACPI_CONSUMER;
resource->res.data.extended_irq.edge_level = link->irq.edge_level;
resource->res.data.extended_irq.active_high_low = link->irq.active_high_low;
if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
resource.res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
resource->res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
else
resource.res.data.irq.shared_exclusive = ACPI_SHARED;
resource.res.data.extended_irq.number_of_interrupts = 1;
resource.res.data.extended_irq.interrupts[0] = irq;
resource->res.data.irq.shared_exclusive = ACPI_SHARED;
resource->res.data.extended_irq.number_of_interrupts = 1;
resource->res.data.extended_irq.interrupts[0] = irq;
/* ignore resource_source, it's optional */
break;
default:
printk("ACPI BUG: resource_type %d\n", link->irq.resource_type);
return_VALUE(-EINVAL);
result = -EINVAL;
goto end;
}
resource.end.id = ACPI_RSTYPE_END_TAG;
resource->end.id = ACPI_RSTYPE_END_TAG;
/* Attempt to set the resource */
status = acpi_set_current_resources(link->handle, &buffer);
......@@ -358,14 +365,15 @@ acpi_pci_link_set (
/* check for total failure */
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SRS\n"));
return_VALUE(-ENODEV);
result = -ENODEV;
goto end;
}
/* Query _STA, set device->status */
result = acpi_bus_get_status(link->device);
if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n"));
return_VALUE(result);
goto end;
}
if (!link->device->status.enabled) {
printk(KERN_WARNING PREFIX
......@@ -377,7 +385,7 @@ acpi_pci_link_set (
/* Query _CRS, set link->irq.active */
result = acpi_pci_link_get_current(link);
if (result) {
return_VALUE(result);
goto end;
}
/*
......@@ -399,7 +407,9 @@ acpi_pci_link_set (
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Set IRQ %d\n", link->irq.active));
return_VALUE(0);
end:
kfree(resource);
return_VALUE(result);
}
......
......@@ -64,6 +64,7 @@
#define ACPI_THERMAL_PATH_POWEROFF "/sbin/poweroff"
#define ACPI_THERMAL_MAX_ACTIVE 10
#define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65
#define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732>=0) ? ((long)t-2732+5)/10 : ((long)t-2732-5)/10)
#define CELSIUS_TO_KELVIN(t) ((t+273)*10)
......@@ -899,21 +900,33 @@ acpi_thermal_write_trip_points (
struct seq_file *m = (struct seq_file *)file->private_data;
struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
char limit_string[65] = {'\0'};
char *limit_string;
int num, critical, hot, passive;
int active[ACPI_THERMAL_MAX_ACTIVE];
int *active;
int i = 0;
ACPI_FUNCTION_TRACE("acpi_thermal_write_trip_points");
limit_string = kmalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL);
if(!limit_string)
return_VALUE(-ENOMEM);
memset(limit_string, 0, ACPI_THERMAL_MAX_LIMIT_STR_LEN);
active = kmalloc(ACPI_THERMAL_MAX_ACTIVE *sizeof(int), GFP_KERNEL);
if(!active)
return_VALUE(-ENOMEM);
if (!tz || (count > sizeof(limit_string) - 1)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n"));
return_VALUE(-EINVAL);
count = -EINVAL;
goto end;
}
if (copy_from_user(limit_string, buffer, count)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n"));
return_VALUE(-EFAULT);
count = -EFAULT;
goto end;
}
limit_string[count] = '\0';
......@@ -924,7 +937,8 @@ acpi_thermal_write_trip_points (
&active[5], &active[6], &active[7], &active[8], &active[9]);
if(!(num >=5 && num < (ACPI_THERMAL_MAX_ACTIVE + 3))) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));
return_VALUE(-EINVAL);
count = -EINVAL;
goto end;
}
tz->trips.critical.temperature = CELSIUS_TO_KELVIN(critical);
......@@ -936,6 +950,9 @@ acpi_thermal_write_trip_points (
tz->trips.active[i].temperature = CELSIUS_TO_KELVIN(active[i]);
}
end:
kfree(active);
kfree(limit_string);
return_VALUE(count);
}
......
......@@ -242,6 +242,13 @@ static struct file_operations acpi_video_device_EDID_fops = {
.release = single_release,
};
static char device_decode[][30] = {
"motherboard VGA device",
"PCI VGA device",
"AGP VGA device",
"UNKNOWN",
};
static void acpi_video_device_notify ( acpi_handle handle, u32 event, void *data);
static void acpi_video_device_rebind( struct acpi_video_bus *video);
static void acpi_video_device_bind( struct acpi_video_bus *video, struct acpi_video_device *device);
......@@ -1117,12 +1124,6 @@ acpi_video_bus_POST_seq_show (
struct acpi_video_bus *video = (struct acpi_video_bus *) seq->private;
int status;
unsigned long id;
char device_decode[][30] = {
"motherboard VGA device",
"PCI VGA device",
"AGP VGA device",
"UNKNOWN",
};
ACPI_FUNCTION_TRACE("acpi_video_bus_POST_seq_show");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment