diff options
author | dumbbell <dumbbell@FreeBSD.org> | 2018-11-06 06:32:41 +0800 |
---|---|---|
committer | dumbbell <dumbbell@FreeBSD.org> | 2018-11-06 06:32:41 +0800 |
commit | fe5125ade0f4ab65a59fd98d5bd2ecce976659cc (patch) | |
tree | 17fe10cb592f1e369de364ee9ee78224867762a5 | |
parent | 19cae68eb2f2f8b9ca106fbde0924557f649757c (diff) | |
download | freebsd-ports-gnome-fe5125ade0f4ab65a59fd98d5bd2ecce976659cc.tar.gz freebsd-ports-gnome-fe5125ade0f4ab65a59fd98d5bd2ecce976659cc.tar.zst freebsd-ports-gnome-fe5125ade0f4ab65a59fd98d5bd2ecce976659cc.zip |
sysutils/acpi_call: Fix kernel panic since r336876
PR: 230993
Submitted by: D Scott Phillips <d.scott.phillips@intel.com>
Reported by: Theron Tarigo <theron.tarigo@gmail.com>
MFH: 2018Q4
-rw-r--r-- | sysutils/acpi_call/Makefile | 1 | ||||
-rw-r--r-- | sysutils/acpi_call/files/patch-acpi__call.c | 138 |
2 files changed, 139 insertions, 0 deletions
diff --git a/sysutils/acpi_call/Makefile b/sysutils/acpi_call/Makefile index c9a84078a7ae..478f1b521ddd 100644 --- a/sysutils/acpi_call/Makefile +++ b/sysutils/acpi_call/Makefile @@ -3,6 +3,7 @@ PORTNAME= acpi_call PORTVERSION= 1.0.1 +PORTREVISION= 1 CATEGORIES= sysutils MASTER_SITES= http://projects.ukrweb.net/files/ \ http://imax.in.ua/files/ diff --git a/sysutils/acpi_call/files/patch-acpi__call.c b/sysutils/acpi_call/files/patch-acpi__call.c new file mode 100644 index 000000000000..fbae58efa103 --- /dev/null +++ b/sysutils/acpi_call/files/patch-acpi__call.c @@ -0,0 +1,138 @@ +--- acpi_call.c.orig 2011-11-07 05:35:10 UTC ++++ acpi_call.c +@@ -45,18 +45,97 @@ + + void acpi_call_fixup_pointers(ACPI_OBJECT *p, UINT8 *orig); + ++static void ++free_acpi_object_list(ACPI_OBJECT_LIST *list) ++{ ++ for (int i = 0; i < list->Count; i++) { ++ switch (list->Pointer[i].Type) { ++ case ACPI_TYPE_STRING: ++ AcpiOsFree(list->Pointer[i].String.Pointer); ++ break; ++ case ACPI_TYPE_BUFFER: ++ AcpiOsFree(list->Pointer[i].Buffer.Pointer); ++ break; ++ default: ++ break; ++ } ++ } ++ AcpiOsFree(list); ++} ++ ++static ACPI_OBJECT_LIST * ++copyin_acpi_object_list(ACPI_OBJECT_LIST *src) ++{ ++ ACPI_OBJECT_LIST *dest; ++ bool failed; ++ ++ if (src->Count > 7) ++ return NULL; ++ ++ dest = AcpiOsAllocate(sizeof(ACPI_OBJECT_LIST) + sizeof(ACPI_OBJECT) * src->Count); ++ if (!dest) ++ return NULL; ++ ++ dest->Count = src->Count; ++ dest->Pointer = (ACPI_OBJECT *)(dest + 1); ++ if (copyin(src->Pointer, dest->Pointer, sizeof(ACPI_OBJECT) * dest->Count)) { ++ AcpiOsFree(dest); ++ return NULL; ++ } ++ ++ failed = false; ++ ++ for (int i = 0; i < dest->Count; i++) { ++ switch (dest->Pointer[i].Type) { ++ case ACPI_TYPE_INTEGER: ++ break; ++ case ACPI_TYPE_STRING: { ++ void *v = AcpiOsAllocate(dest->Pointer[i].String.Length); ++ if (!v || copyin(dest->Pointer[i].String.Pointer, v, dest->Pointer[i].String.Length)) ++ failed = true; ++ dest->Pointer[i].String.Pointer = v; ++ break; ++ } ++ case ACPI_TYPE_BUFFER: { ++ void *v = AcpiOsAllocate(dest->Pointer[i].Buffer.Length); ++ if (!v || copyin(dest->Pointer[i].Buffer.Pointer, v, dest->Pointer[i].Buffer.Length)) ++ failed = true; ++ dest->Pointer[i].String.Pointer = v; ++ break; ++ } ++ default: ++ failed = true; ++ break; ++ } ++ } ++ ++ if (failed) { ++ free_acpi_object_list(dest); ++ dest = NULL; ++ } ++ ++ return dest; ++} ++ + static int + acpi_call_ioctl(u_long cmd, caddr_t addr, void *arg) + { + struct acpi_call_descr *params; ++ ACPI_OBJECT_LIST *args; + ACPI_BUFFER result; ++ char path[256]; + + result.Length = ACPI_ALLOCATE_BUFFER; + result.Pointer = NULL; + + if (cmd == ACPIIO_CALL) { + params = (struct acpi_call_descr*)addr; +- params->retval = AcpiEvaluateObject(NULL, params->path, ¶ms->args, &result); ++ args = copyin_acpi_object_list(¶ms->args); ++ if (!args) ++ return EINVAL; ++ if (copyinstr(params->path, path, sizeof(path), NULL)) ++ return EINVAL; ++ params->retval = AcpiEvaluateObject(NULL, path, args, &result); + if (ACPI_SUCCESS(params->retval)) + { + if (result.Pointer != NULL) +@@ -64,30 +143,31 @@ acpi_call_ioctl(u_long cmd, caddr_t addr, void *arg) + if (params->result.Pointer != NULL) + { + params->result.Length = min(params->result.Length, result.Length); ++ if (result.Length >= sizeof(ACPI_OBJECT)) ++ acpi_call_fixup_pointers((ACPI_OBJECT*)result.Pointer, params->result.Pointer); + copyout(result.Pointer, params->result.Pointer, + params->result.Length); + params->reslen = result.Length; +- if (result.Length >= sizeof(ACPI_OBJECT)) +- acpi_call_fixup_pointers((ACPI_OBJECT*)(params->result.Pointer), result.Pointer); + } + AcpiOsFree(result.Pointer); + } + } ++ free_acpi_object_list(args); + } + + return (0); + } + + void +-acpi_call_fixup_pointers(ACPI_OBJECT *p, UINT8 *orig) ++acpi_call_fixup_pointers(ACPI_OBJECT *p, UINT8 *dest) + { + switch (p->Type) + { + case ACPI_TYPE_STRING: +- p->String.Pointer = (char*)((UINT8*)(p->String.Pointer) - orig + (UINT8*)p); ++ p->String.Pointer += dest - (UINT8*)p; + break; + case ACPI_TYPE_BUFFER: +- p->Buffer.Pointer -= orig - (UINT8*)p; ++ p->Buffer.Pointer += dest - (UINT8*)p; + break; + } + } |