aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordumbbell <dumbbell@FreeBSD.org>2018-11-06 06:32:41 +0800
committerdumbbell <dumbbell@FreeBSD.org>2018-11-06 06:32:41 +0800
commitfe5125ade0f4ab65a59fd98d5bd2ecce976659cc (patch)
tree17fe10cb592f1e369de364ee9ee78224867762a5
parent19cae68eb2f2f8b9ca106fbde0924557f649757c (diff)
downloadfreebsd-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/Makefile1
-rw-r--r--sysutils/acpi_call/files/patch-acpi__call.c138
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, &params->args, &result);
++ args = copyin_acpi_object_list(&params->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;
+ }
+ }