mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 18:21:24 +02:00
ACPICA: Improve argument parsing in acpi_ps_get_next_simple_arg()
Improve argument parsing in acpi_ps_get_next_simple_arg() to handle remaining AML data safely. Link: https://github.com/acpica/acpica/commit/ecbb8bcfe301 Signed-off-by: ikaros <void0red@gmail.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Link: https://patch.msgid.link/2008043.taCxCBeP46@rafael.j.wysocki
This commit is contained in:
parent
0e2021f49e
commit
27d27e75ec
|
|
@ -384,6 +384,8 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
|
|||
u32 length;
|
||||
u16 opcode;
|
||||
u8 *aml = parser_state->aml;
|
||||
u32 remaining = (u32)ACPI_PTR_DIFF(parser_state->aml_end, aml);
|
||||
u64 partial_value;
|
||||
|
||||
ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg, arg_type);
|
||||
|
||||
|
|
@ -393,8 +395,13 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
|
|||
/* Get 1 byte from the AML stream */
|
||||
|
||||
opcode = AML_BYTE_OP;
|
||||
arg->common.value.integer = (u64) *aml;
|
||||
length = 1;
|
||||
if (remaining >= 1) {
|
||||
arg->common.value.integer = (u64)*aml;
|
||||
length = 1;
|
||||
} else {
|
||||
arg->common.value.integer = 0;
|
||||
length = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ARGP_WORDDATA:
|
||||
|
|
@ -402,8 +409,19 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
|
|||
/* Get 2 bytes from the AML stream */
|
||||
|
||||
opcode = AML_WORD_OP;
|
||||
ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
|
||||
length = 2;
|
||||
if (remaining >= 2) {
|
||||
ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
|
||||
length = 2;
|
||||
} else {
|
||||
arg->common.value.integer = 0;
|
||||
length = 0;
|
||||
if (remaining > 0) {
|
||||
partial_value = 0;
|
||||
memcpy(&partial_value, aml, remaining);
|
||||
arg->common.value.integer = partial_value;
|
||||
length = remaining;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ARGP_DWORDDATA:
|
||||
|
|
@ -411,8 +429,19 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
|
|||
/* Get 4 bytes from the AML stream */
|
||||
|
||||
opcode = AML_DWORD_OP;
|
||||
ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
|
||||
length = 4;
|
||||
if (remaining >= 4) {
|
||||
ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
|
||||
length = 4;
|
||||
} else {
|
||||
arg->common.value.integer = 0;
|
||||
length = 0;
|
||||
if (remaining > 0) {
|
||||
partial_value = 0;
|
||||
memcpy(&partial_value, aml, remaining);
|
||||
arg->common.value.integer = partial_value;
|
||||
length = remaining;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ARGP_QWORDDATA:
|
||||
|
|
@ -420,8 +449,19 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
|
|||
/* Get 8 bytes from the AML stream */
|
||||
|
||||
opcode = AML_QWORD_OP;
|
||||
ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
|
||||
length = 8;
|
||||
if (remaining >= 8) {
|
||||
ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
|
||||
length = 8;
|
||||
} else {
|
||||
arg->common.value.integer = 0;
|
||||
length = 0;
|
||||
if (remaining > 0) {
|
||||
partial_value = 0;
|
||||
memcpy(&partial_value, aml, remaining);
|
||||
arg->common.value.integer = partial_value;
|
||||
length = remaining;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ARGP_CHARLIST:
|
||||
|
|
@ -434,10 +474,28 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
|
|||
/* Find the null terminator */
|
||||
|
||||
length = 0;
|
||||
while (aml[length]) {
|
||||
while ((length < remaining) && aml[length]) {
|
||||
length++;
|
||||
}
|
||||
length++;
|
||||
if (length < remaining) {
|
||||
|
||||
/* Account for the terminating null */
|
||||
length++;
|
||||
} else {
|
||||
/*
|
||||
* No terminator found - add null at buffer boundary
|
||||
* and report a warning
|
||||
*/
|
||||
ACPI_WARNING((AE_INFO,
|
||||
"Invalid AML string: no null terminator, truncating at offset %u",
|
||||
(u32)(aml - parser_state->aml)));
|
||||
|
||||
/* Add null terminator at the boundary */
|
||||
if (remaining > 0) {
|
||||
aml[remaining - 1] = 0;
|
||||
length = remaining;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ARGP_NAME:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user