> Date: Sat, 28 Mar 2015 23:27:30 +1000
> From: Jonathan Matthew <jonat...@d14n.org>
> 
> The diff below fixes a uvm fault I'm seeing when booting an MP kernel on a
> hp bc2500 blade, somewhere during acpi attach.  SP kernels don't crash, but
> I think that's down to luck.  It looks like this:
> 
> ioapic0 at mainbus0: apid 2 pa 0xfec00000, version 21, 24 pins
> acpimcfg0 at acpi0 addr 0xe0000000, bus 0-64
> acpihpet0 at acpi0: 14318180 Hz
> uvm_fault(0xffffffff818c5860, 0xffff800000063000, 0, 1) -> e
> kernel: page fault trap, code=0
> Stopped at      memcpy+0xa:     repe movsq      (%rsi),%es:(%rdi)
> memcpy() at memcpy+0xa
> aml_rwfield() at aml_rwfield+0x205
> aml_store() at aml_store+0x1eb
> aml_parse() at aml_parse+0xf4c
> aml_eval() at aml_eval+0x1c8
> aml_parse() at aml_parse+0x183d
> aml_eval() at aml_eval+0x1c8
> aml_evalnode() at aml_evalnode+0x74
> acpi_inidev() at acpi_inidev+0x57
> aml_find_node() at aml_find_node+0x92
> end trace frame: 0xffffffff81a1eab0, count: 0
> 
> This turns out to be because aml_rwgas doesn't do bounds checking on source
> buffers.
> 
> _SB.PCI0._INI (evaluated in acpi_inidev) tries to figure out what OS is
> running.  The method it calls to do this creates a temporary buffer:
> 
>             Name (STR0, Buffer (0x50) {})
> 
> that it copies some lies into, like "Microsoft Windows Vista", then copies 
> that
> somewhere else:
> 
>             WMIB = STR0 /* \OSFG.STR0 */
> 
> where WMIB is:
> 
>     OperationRegion (HABS, SystemMemory, HBIO, HBSZ)
>     Field (HABS, AnyAcc, NoLock, Preserve)
>     {
>         WMIB,   33280, 
> 
> which is a fair bit bigger than the STR0 buffer.  aml_rwgas tries to read all
> 33280 bits from STR0 anyway, which obviously leads to crashes.
> 
> I've tested the fix on several machines running amd64 and i386 and nothing
> breaks as far as I can tell.
> 
> oks, more tests, etc.?

ok kettenis@

> Index: dsdt.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
> retrieving revision 1.216
> diff -u -p -u -p -r1.216 dsdt.c
> --- dsdt.c    16 Mar 2015 20:31:46 -0000      1.216
> +++ dsdt.c    28 Mar 2015 11:57:07 -0000
> @@ -2286,6 +2286,9 @@ aml_rwgas(struct aml_value *rgn, int bpo
>               } else {
>                       /* Write to a large field.. create or convert buffer */
>                       val = aml_convert(val, AML_OBJTYPE_BUFFER, -1);
> +
> +                     if (blen > (val->length << 3))
> +                             blen = val->length << 3;
>               }
>               vbit = val->v_buffer;
>       } else {
> 
> 

Reply via email to