> Date: Sat, 28 Mar 2015 23:27:30 +1000
> From: Jonathan Matthew <[email protected]>
>
> 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 {
>
>