Module Name:    src
Committed By:   martin
Date:           Sun Apr 12 08:48:57 UTC 2020

Modified Files:
        src/sys/dev/acpi [netbsd-9]: acpi_ec.c

Log Message:
Pull up following revision(s) (requested by riastradh in ticket #829):

        sys/dev/acpi/acpi_ec.c: revision 1.78
        sys/dev/acpi/acpi_ec.c: revision 1.79
        sys/dev/acpi/acpi_ec.c: revision 1.80
        sys/dev/acpi/acpi_ec.c: revision 1.81

Revert acpi_ec.c 1.77.
We will do this another way.
ok msaitoh

Revert acpi_ec.c 1.76.
We will do this another way, and separate KNF fixes from the critical
functional change.
ok msaitoh

KNF

Reject overly large widths, from mlelstv.
We are returning an ACPI_INTEGER (= uint64_t), so it doesn't make
sense to handle more than 64 bits.

Apparently there are some ACPIs out there that ask for unreasonably
large widths here.  Just reject those requests, rather than writing
past the caller's stack buffer.

Previously we attempted to fix this by copying byte by byte as large
as the caller asked, in order to avoid the undefined behaviour of
shifting past the size of ACPI_INTEGER, but that just turned a shift
(which might have been harmless on real machines) into a stack buffer
overflow (!).

ok msaitoh


To generate a diff of this commit:
cvs rdiff -u -r1.75.20.1 -r1.75.20.2 src/sys/dev/acpi/acpi_ec.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/acpi/acpi_ec.c
diff -u src/sys/dev/acpi/acpi_ec.c:1.75.20.1 src/sys/dev/acpi/acpi_ec.c:1.75.20.2
--- src/sys/dev/acpi/acpi_ec.c:1.75.20.1	Fri Aug  9 16:13:35 2019
+++ src/sys/dev/acpi/acpi_ec.c	Sun Apr 12 08:48:56 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: acpi_ec.c,v 1.75.20.1 2019/08/09 16:13:35 martin Exp $	*/
+/*	$NetBSD: acpi_ec.c,v 1.75.20.2 2020/04/12 08:48:56 martin Exp $	*/
 
 /*-
  * Copyright (c) 2007 Joerg Sonnenberger <jo...@netbsd.org>.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_ec.c,v 1.75.20.1 2019/08/09 16:13:35 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_ec.c,v 1.75.20.2 2020/04/12 08:48:56 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/callout.h>
@@ -657,36 +657,42 @@ static ACPI_STATUS
 acpiec_space_handler(uint32_t func, ACPI_PHYSICAL_ADDRESS paddr,
     uint32_t width, ACPI_INTEGER *value, void *arg, void *region_arg)
 {
-	device_t dv = arg;
+	device_t dv;
 	ACPI_STATUS rv;
-	uint8_t addr;
-	uint8_t *reg;
+	uint8_t addr, reg;
+	unsigned int i;
 
-	if ((func != ACPI_READ) && (func != ACPI_WRITE)) {
-		aprint_error("%s: invalid Address Space function called: %x\n",
-		    device_xname(dv), (unsigned int)func);
-		return AE_BAD_PARAMETER;
-	}
-	if (paddr > 0xff || width % 8 != 0 || value == NULL || arg == NULL ||
-	    paddr + width / 8 > 0x100)
+	if (paddr > 0xff || width % 8 != 0 || width > sizeof(ACPI_INTEGER)*8 ||
+	    value == NULL || arg == NULL || paddr + width / 8 > 0x100)
 		return AE_BAD_PARAMETER;
 
 	addr = paddr;
-	reg = (uint8_t *)value;
+	dv = arg;
 
 	rv = AE_OK;
 
-	if (func == ACPI_READ)
+	switch (func) {
+	case ACPI_READ:
 		*value = 0;
-
-	for (addr = paddr; addr < (paddr + width / 8); addr++, reg++) {
-		if (func == ACPI_READ)
-			rv = acpiec_read(dv, addr, reg);
-		else
-			rv = acpiec_write(dv, addr, *reg);
-
-		if (rv != AE_OK)
-			break;
+		for (i = 0; i < width; i += 8, ++addr) {
+			rv = acpiec_read(dv, addr, &reg);
+			if (rv != AE_OK)
+				break;
+			*value |= (ACPI_INTEGER)reg << i;
+		}
+		break;
+	case ACPI_WRITE:
+		for (i = 0; i < width; i += 8, ++addr) {
+			reg = (*value >> i) & 0xff;
+			rv = acpiec_write(dv, addr, reg);
+			if (rv != AE_OK)
+				break;
+		}
+		break;
+	default:
+		aprint_error("%s: invalid Address Space function called: %x\n",
+		    device_xname(dv), (unsigned int)func);
+		return AE_BAD_PARAMETER;
 	}
 
 	return rv;

Reply via email to