Hi,

My vaio repeatedly crashed by "Data modified on freelist"(*1) or other
memory corruptions.  After my long time debug, I found the route cause
is a handling of references of LocalX, like the following:

                    If ((SMRW (0x0B, 0x16, 0x21, RefOf (Local0)) == Zero))

In the called control method, "RefOf (Local1)" is referred as Arg3, is
stored a value like the following:

                        Arg3 = \_SB.PCI0.LPCB.EC0.SMD0

In aml_store(), lvalue is reset if lvalue is a LocalX.  But since that
was done before resolving the reference, lvalue was not reset if
lvalue is a reference of LocalX.

diff #1 fixes that problem.  It resets lvalue after resolving
references.

ok?

diff #2 adds aml_die() if any memory corruption occurs when creating
field in a buffer.  This actually happens on my vaio (pro pk 14) if
diff #1 is not applied.

ok?

diff #1

Index: sys/dev/acpi/dsdt.c
===================================================================
RCS file: /var/cvs/openbsd/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.257
diff -u -p -r1.257 dsdt.c
--- sys/dev/acpi/dsdt.c 17 Dec 2020 17:57:19 -0000      1.257
+++ sys/dev/acpi/dsdt.c 26 Feb 2021 04:12:03 -0000
@@ -2961,11 +2961,11 @@ aml_store(struct aml_scope *scope, struc
                aml_rwfield(rhs, 0, rhs->v_field.bitlen, &tmp, ACPI_IOREAD);
                rhs = &tmp;
        }
+
+       lhs = aml_gettgt(lhs, AMLOP_STORE);
        /* Store to LocalX: free value */
        if (lhs->stack >= AMLOP_LOCAL0 && lhs->stack <= AMLOP_LOCAL7)
                aml_freevalue(lhs);
-
-       lhs = aml_gettgt(lhs, AMLOP_STORE);
        switch (lhs->type) {
        case AML_OBJTYPE_UNINITIALIZED:
                aml_copyvalue(lhs, rhs);

diff #2

Index: sys/dev/acpi/dsdt.c
===================================================================
RCS file: /var/cvs/openbsd/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.257
diff -u -p -r1.257 dsdt.c
--- sys/dev/acpi/dsdt.c 17 Dec 2020 17:57:19 -0000      1.257
+++ sys/dev/acpi/dsdt.c 26 Feb 2021 04:33:21 -0000
@@ -2742,11 +2742,17 @@ aml_rwfield(struct aml_value *fld, int b
        } else if (mode == ACPI_IOREAD) {
                /* bufferfield:read */
                _aml_setvalue(val, AML_OBJTYPE_INTEGER, 0, 0);
+               if (ref1->length < aml_bytepos(fld->v_field.bitpos) +
+                   aml_bytelen(fld->v_field.bitlen))
+                       aml_die("bufferfield:read out of range");
                aml_bufcpy(&val->v_integer, 0, ref1->v_buffer,
                    fld->v_field.bitpos, fld->v_field.bitlen);
        } else {
                /* bufferfield:write */
                val = aml_convert(val, AML_OBJTYPE_INTEGER, -1);
+               if (ref1->length < aml_bytepos(fld->v_field.bitpos) +
+                   aml_bytelen(fld->v_field.bitlen))
+                       aml_die("bufferfield:write out of range");
                aml_bufcpy(ref1->v_buffer, fld->v_field.bitpos, &val->v_integer,
                    0, fld->v_field.bitlen);
                aml_delref(&val, "wrbuffld");


*1 example console log

    Data modified on freelist: word -35183627074926 of object 
0xffff8000024a3060 size 0x10 previous type temp (invalid addr 
0xffff8027023e55f0)
    uvm_fault(0xffffffff81f63958, 0xffff8027023e55f8, 0, 1) -> e
    kernel: page fault trap, code=0
    Stopped at      malloc+0x482:   movq    0x8(%r14),%rcx
    Running script...
    ddb{0}> malloc(10,91,5) at malloc+0x482
    
i915_gem_do_execbuffer(ffff8000002ab078,ffff800000ee0c00,ffff8000337a7970,ffff8000020ca000,0)
 at i915_gem_do_execbuffer+0xa52
    
i915_gem_execbuffer2_ioctl(ffff8000002ab078,ffff8000337a7970,ffff800000ee0c00) 
at i915_gem_execbuffer2_ioctl+0x144
    drmioctl(15700,80406469,ffff8000337a7970,3,ffff8000336a8798) at 
drmioctl+0xd8
    
VOP_IOCTL(fffffd8227abbeb0,80406469,ffff8000337a7970,3,fffffd826bd1dd88,ffff8000336a8798)
 at VOP_IOCTL+0x55
    vn_ioctl(fffffd82282ee8e8,80406469,ffff8000337a7970,ffff8000336a8798) at 
vn_ioctl+0x64
    sys_ioctl(ffff8000336a8798,ffff8000337a7a80,ffff8000337a7ae0) at 
sys_ioctl+0x3c2
    syscall(ffff8000337a7b50) at syscall+0x389
    Xsyscall(6,36,0,36,80406469,7f7fffff5c00) at Xsyscall+0x128
    end of kernel
    end trace frame: 0x7f7fffff5bd0, count: -9

Reply via email to