diff options
author | Can Erkin Acar <canacar@cvs.openbsd.org> | 2007-11-03 19:06:08 +0000 |
---|---|---|
committer | Can Erkin Acar <canacar@cvs.openbsd.org> | 2007-11-03 19:06:08 +0000 |
commit | 8d47b36de2cf57509703a9cefd4621968f5becd6 (patch) | |
tree | 8269394177dd83e1c07fddc8f9afad09055e9e25 /sys/dev/acpi | |
parent | 0c68de5a9eaaa31381b79595d4441f63aa3db9fd (diff) |
Fix setting values to buffers by obeying the conversion rules.
The values are truncated or zero extended as required. The spec
is somewhat ambigious on strings and integers requiring truncation
"before copy" so we try to be safe and zero terminate the buffer
in case the source is string.
Reported by ckuethe@, diagnosis, initial diff and feedback by kettenis@
ok kettenis@, beck@, weingart@, robert@, gwk@, ckuethe@
Diffstat (limited to 'sys/dev/acpi')
-rw-r--r-- | sys/dev/acpi/dsdt.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c index e11a74e9044..8d7c6a5ce14 100644 --- a/sys/dev/acpi/dsdt.c +++ b/sys/dev/acpi/dsdt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dsdt.c,v 1.93 2007/11/03 17:48:10 ckuethe Exp $ */ +/* $OpenBSD: dsdt.c,v 1.94 2007/11/03 19:06:07 canacar Exp $ */ /* * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> * @@ -1621,24 +1621,38 @@ aml_setvalue(struct aml_scope *scope, struct aml_value *lhs, lhs->v_integer = aml_val2int(rhs); break; case AML_OBJTYPE_BUFFER: + { + char *buf; + int len; + if (lhs->node) dnprintf(40, "named.buffer\n"); - aml_freevalue(lhs); - if (rhs->type == AML_OBJTYPE_BUFFER) - _aml_setvalue(lhs, AML_OBJTYPE_BUFFER, rhs->length, - rhs->v_buffer); - else if (rhs->type == AML_OBJTYPE_INTEGER || - rhs->type == AML_OBJTYPE_STATICINT) - _aml_setvalue(lhs, AML_OBJTYPE_BUFFER, - sizeof(rhs->v_integer), &rhs->v_integer); - else if (rhs->type == AML_OBJTYPE_STRING) - _aml_setvalue(lhs, AML_OBJTYPE_BUFFER, rhs->length+1, - rhs->v_string); - else { + + if (rhs->type == AML_OBJTYPE_BUFFER) { + buf = rhs->v_buffer; + len = rhs->length; + } else if (rhs->type == AML_OBJTYPE_INTEGER || + rhs->type == AML_OBJTYPE_STATICINT) { + buf = (char *)&rhs->v_integer; + len = sizeof(rhs->v_integer); + } else if (rhs->type == AML_OBJTYPE_STRING) { + len = rhs->length + 1; + buf = rhs->v_string; + } else { /* aml_showvalue(rhs); */ aml_die("setvalue.buf : %x", aml_pc(scope->pos)); } + if (lhs->length < len) + len = lhs->length; + else + memset(lhs->v_buffer, 0, lhs->length); + memcpy(lhs->v_buffer, buf, len); + /* XXX ACPI v30b 17.2.5.7 says truncate string "before + copying", so make sure the string is terminated */ + if (rhs->type == AML_OBJTYPE_STRING) + lhs->v_buffer[lhs->length - 1] = '\0'; break; + } case AML_OBJTYPE_STRING: if (lhs->node) dnprintf(40, "named string\n"); |