Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-9]: src/sys/dev/acpi Pull up following revision(s) (requested by ...



details:   https://anonhg.NetBSD.org/src/rev/b9ccaf3d4f06
branches:  netbsd-9
changeset: 963776:b9ccaf3d4f06
user:      martin <martin%NetBSD.org@localhost>
date:      Sun Apr 12 08:48:56 2020 +0000

description:
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

diffstat:

 sys/dev/acpi/acpi_ec.c |  52 +++++++++++++++++++++++++++----------------------
 1 files changed, 29 insertions(+), 23 deletions(-)

diffs (82 lines):

diff -r d9c41a457d93 -r b9ccaf3d4f06 sys/dev/acpi/acpi_ec.c
--- a/sys/dev/acpi/acpi_ec.c    Sun Apr 12 08:45:29 2020 +0000
+++ b/sys/dev/acpi/acpi_ec.c    Sun Apr 12 08:48:56 2020 +0000
@@ -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 <joerg%NetBSD.org@localhost>.
@@ -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 @@
 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;



Home | Main Index | Thread Index | Old Index