> 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 { > >