aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2008-08-03 23:13:01 -0400
committerAndi Kleen <ak@linux.intel.com>2008-08-14 20:12:16 -0400
commit3c7db22a194d3b53584047425af82b4e1e03d9f7 (patch)
tree96462093e2826ca81641ccef7ae5718ce2b9c9bb
parentd3ff268a0149fce8835f6d48ab481d5e3321e0f7 (diff)
ACPICA: Additional error checking for pathname utilities
Add error check after all calls to acpi_ns_get_pathname_length. Add status return from acpi_ns_build_external_path and check after all calls. Add parameter validation to acpi_ut_initialize_buffer. Reported by and initial patch by Ingo Molnar. http://lkml.org/lkml/2008/7/21/176 Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Andi Kleen <ak@linux.intel.com>
-rw-r--r--drivers/acpi/namespace/nsnames.c34
-rw-r--r--drivers/acpi/resources/rscalc.c3
-rw-r--r--drivers/acpi/utilities/utalloc.c8
-rw-r--r--drivers/acpi/utilities/utobject.c13
-rw-r--r--include/acpi/acnamesp.h2
5 files changed, 40 insertions, 20 deletions
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
index 549db42f16cf..bd5773878009 100644
--- a/drivers/acpi/namespace/nsnames.c
+++ b/drivers/acpi/namespace/nsnames.c
@@ -56,13 +56,14 @@ ACPI_MODULE_NAME("nsnames")
56 * Size - Size of the pathname 56 * Size - Size of the pathname
57 * *name_buffer - Where to return the pathname 57 * *name_buffer - Where to return the pathname
58 * 58 *
59 * RETURN: Places the pathname into the name_buffer, in external format 59 * RETURN: Status
60 * Places the pathname into the name_buffer, in external format
60 * (name segments separated by path separators) 61 * (name segments separated by path separators)
61 * 62 *
62 * DESCRIPTION: Generate a full pathaname 63 * DESCRIPTION: Generate a full pathaname
63 * 64 *
64 ******************************************************************************/ 65 ******************************************************************************/
65void 66acpi_status
66acpi_ns_build_external_path(struct acpi_namespace_node *node, 67acpi_ns_build_external_path(struct acpi_namespace_node *node,
67 acpi_size size, char *name_buffer) 68 acpi_size size, char *name_buffer)
68{ 69{
@@ -77,7 +78,7 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node,
77 if (index < ACPI_NAME_SIZE) { 78 if (index < ACPI_NAME_SIZE) {
78 name_buffer[0] = AML_ROOT_PREFIX; 79 name_buffer[0] = AML_ROOT_PREFIX;
79 name_buffer[1] = 0; 80 name_buffer[1] = 0;
80 return; 81 return (AE_OK);
81 } 82 }
82 83
83 /* Store terminator byte, then build name backwards */ 84 /* Store terminator byte, then build name backwards */
@@ -105,11 +106,13 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node,
105 106
106 if (index != 0) { 107 if (index != 0) {
107 ACPI_ERROR((AE_INFO, 108 ACPI_ERROR((AE_INFO,
108 "Could not construct pathname; index=%X, size=%X, Path=%s", 109 "Could not construct external pathname; index=%X, size=%X, Path=%s",
109 (u32) index, (u32) size, &name_buffer[size])); 110 (u32) index, (u32) size, &name_buffer[size]));
111
112 return (AE_BAD_PARAMETER);
110 } 113 }
111 114
112 return; 115 return (AE_OK);
113} 116}
114 117
115#ifdef ACPI_DEBUG_OUTPUT 118#ifdef ACPI_DEBUG_OUTPUT
@@ -129,6 +132,7 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node,
129 132
130char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) 133char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
131{ 134{
135 acpi_status status;
132 char *name_buffer; 136 char *name_buffer;
133 acpi_size size; 137 acpi_size size;
134 138
@@ -138,8 +142,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
138 142
139 size = acpi_ns_get_pathname_length(node); 143 size = acpi_ns_get_pathname_length(node);
140 if (!size) { 144 if (!size) {
141 ACPI_ERROR((AE_INFO, "Invalid node failure")); 145 return (NULL);
142 return_PTR(NULL);
143 } 146 }
144 147
145 /* Allocate a buffer to be returned to caller */ 148 /* Allocate a buffer to be returned to caller */
@@ -152,7 +155,11 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
152 155
153 /* Build the path in the allocated buffer */ 156 /* Build the path in the allocated buffer */
154 157
155 acpi_ns_build_external_path(node, size, name_buffer); 158 status = acpi_ns_build_external_path(node, size, name_buffer);
159 if (ACPI_FAILURE(status)) {
160 return (NULL);
161 }
162
156 return_PTR(name_buffer); 163 return_PTR(name_buffer);
157} 164}
158#endif 165#endif
@@ -186,7 +193,7 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
186 while (next_node && (next_node != acpi_gbl_root_node)) { 193 while (next_node && (next_node != acpi_gbl_root_node)) {
187 if (ACPI_GET_DESCRIPTOR_TYPE(next_node) != ACPI_DESC_TYPE_NAMED) { 194 if (ACPI_GET_DESCRIPTOR_TYPE(next_node) != ACPI_DESC_TYPE_NAMED) {
188 ACPI_ERROR((AE_INFO, 195 ACPI_ERROR((AE_INFO,
189 "Invalid NS Node (%p) while traversing path", 196 "Invalid Namespace Node (%p) while traversing namespace",
190 next_node)); 197 next_node));
191 return 0; 198 return 0;
192 } 199 }
@@ -234,8 +241,7 @@ acpi_ns_handle_to_pathname(acpi_handle target_handle,
234 241
235 required_size = acpi_ns_get_pathname_length(node); 242 required_size = acpi_ns_get_pathname_length(node);
236 if (!required_size) { 243 if (!required_size) {
237 ACPI_ERROR((AE_INFO, "Invalid node failure")); 244 return_ACPI_STATUS(AE_BAD_PARAMETER);
238 return_ACPI_STATUS(AE_ERROR);
239 } 245 }
240 246
241 /* Validate/Allocate/Clear caller buffer */ 247 /* Validate/Allocate/Clear caller buffer */
@@ -247,7 +253,11 @@ acpi_ns_handle_to_pathname(acpi_handle target_handle,
247 253
248 /* Build the path in the caller buffer */ 254 /* Build the path in the caller buffer */
249 255
250 acpi_ns_build_external_path(node, required_size, buffer->pointer); 256 status =
257 acpi_ns_build_external_path(node, required_size, buffer->pointer);
258 if (ACPI_FAILURE(status)) {
259 return_ACPI_STATUS(status);
260 }
251 261
252 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X]\n", 262 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X]\n",
253 (char *)buffer->pointer, (u32) required_size)); 263 (char *)buffer->pointer, (u32) required_size));
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index f61ebc679e66..d9063ea414e3 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -587,6 +587,9 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
587 } else { 587 } else {
588 temp_size_needed += 588 temp_size_needed +=
589 acpi_ns_get_pathname_length((*sub_object_list)->reference.node); 589 acpi_ns_get_pathname_length((*sub_object_list)->reference.node);
590 if (!temp_size_needed) {
591 return_ACPI_STATUS(AE_BAD_PARAMETER);
592 }
590 } 593 }
591 } else { 594 } else {
592 /* 595 /*
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index e7bf34a7b1d2..7dcb67e0b215 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -242,10 +242,12 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer,
242{ 242{
243 acpi_status status = AE_OK; 243 acpi_status status = AE_OK;
244 244
245 if (!required_length) { 245 /* Parameter validation */
246 WARN_ON(1); 246
247 return AE_ERROR; 247 if (!buffer || !required_length) {
248 return (AE_BAD_PARAMETER);
248 } 249 }
250
249 switch (buffer->length) { 251 switch (buffer->length) {
250 case ACPI_NO_BUFFER: 252 case ACPI_NO_BUFFER:
251 253
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index e25484495e65..916eff399eb3 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -425,6 +425,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
425 acpi_size * obj_length) 425 acpi_size * obj_length)
426{ 426{
427 acpi_size length; 427 acpi_size length;
428 acpi_size size;
428 acpi_status status = AE_OK; 429 acpi_status status = AE_OK;
429 430
430 ACPI_FUNCTION_TRACE_PTR(ut_get_simple_object_size, internal_object); 431 ACPI_FUNCTION_TRACE_PTR(ut_get_simple_object_size, internal_object);
@@ -484,10 +485,14 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
484 * Get the actual length of the full pathname to this object. 485 * Get the actual length of the full pathname to this object.
485 * The reference will be converted to the pathname to the object 486 * The reference will be converted to the pathname to the object
486 */ 487 */
487 length += 488 size =
488 ACPI_ROUND_UP_TO_NATIVE_WORD 489 acpi_ns_get_pathname_length(internal_object->
489 (acpi_ns_get_pathname_length 490 reference.node);
490 (internal_object->reference.node)); 491 if (!size) {
492 return_ACPI_STATUS(AE_BAD_PARAMETER);
493 }
494
495 length += ACPI_ROUND_UP_TO_NATIVE_WORD(size);
491 break; 496 break;
492 497
493 default: 498 default:
diff --git a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h
index 9ed70a050580..c34008507b69 100644
--- a/include/acpi/acnamesp.h
+++ b/include/acpi/acnamesp.h
@@ -182,7 +182,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info);
182 */ 182 */
183u32 acpi_ns_opens_scope(acpi_object_type type); 183u32 acpi_ns_opens_scope(acpi_object_type type);
184 184
185void 185acpi_status
186acpi_ns_build_external_path(struct acpi_namespace_node *node, 186acpi_ns_build_external_path(struct acpi_namespace_node *node,
187 acpi_size size, char *name_buffer); 187 acpi_size size, char *name_buffer);
188 188