Re: bounds checks in aml_rwgas

2015-04-02 Thread Mark Kettenis
 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 0xfec0, version 21, 24 pins
 acpimcfg0 at acpi0 addr 0xe000, bus 0-64
 acpihpet0 at acpi0: 14318180 Hz
 uvm_fault(0x818c5860, 0x80063000, 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: 0x81a1eab0, 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.c16 Mar 2015 20:31:46 -  1.216
 +++ dsdt.c28 Mar 2015 11:57:07 -
 @@ -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 {
 
 



Re: bounds checks in aml_rwgas

2015-03-29 Thread Jonathan Matthew
On Sat, Mar 28, 2015 at 11:27:30PM +1000, Jonathan Matthew wrote:
 
 The diff below fixes a uvm fault I'm seeing when booting an MP kernel on a
 hp bc2500 blade, somewhere during acpi attach.

Another interesting thing here is that a 5.7ish bsd.rd crashes a bit earlier
(after attaching ioapic0, from what I remember) but the current snapshot bsd.rd
works.  I'm guessing this is due to the recent #ifndef SMALL_KERNEL changes in
acpi.

Also, here's a full dmesg:

OpenBSD 5.7-current (GENERIC.MP) #7: Sat Mar 28 18:02:17 AEST 2015

j...@hp-blade-1-2.eait.uq.edu.au:/home/jono/src/sys/arch/amd64/compile/GENERIC.MP
real mem = 4142628864 (3950MB)
avail mem = 4013219840 (3827MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.4 @ 0xed5f0 (38 entries)
bios0: vendor Hewlett-Packard version 786E5 v02.14 date 08/06/2008
bios0: Hewlett-Packard HP Blade PC bc2500
acpi0 at bios0: rev 0
acpi0: sleep states S0 S5
acpi0: tables DSDT FACP APIC ASF! MCFG TCPA SLIC HPET
acpi0: wakeup devices PCI0(S4) IGFX(S4) PCX1(S4) PCX2(S4) PCX3(S4) HUB_(S4) 
PBTN(S4)
acpitimer0 at acpi0: 3579545 Hz, 32 bits
acpimadt0 at acpi0 addr 0xfee0: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: AMD Athlon(tm) 64 X2 Dual Core Processor 3000+, 1596.23 MHz
cpu0: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,CX16,NXE,MMXX,FFXSR,LONG,3DNOW2,3DNOW,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,3DNOWP
cpu0: 64KB 64b/line 2-way I-cache, 64KB 64b/line 2-way D-cache, 512KB 64b/line 
16-way L2 cache
cpu0: ITLB 32 4KB entries fully associative, 8 4MB entries fully associative
cpu0: DTLB 32 4KB entries fully associative, 8 4MB entries fully associative
mtrr: Pentium Pro MTRR support, 8 var ranges, 88 fixed ranges
cpu0: apic clock running at 199MHz
cpu1 at mainbus0: apid 1 (application processor)
cpu1: AMD Athlon(tm) 64 X2 Dual Core Processor 3000+, 1596.00 MHz
cpu1: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,CX16,NXE,MMXX,FFXSR,LONG,3DNOW2,3DNOW,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,3DNOWP
cpu1: 64KB 64b/line 2-way I-cache, 64KB 64b/line 2-way D-cache, 512KB 64b/line 
16-way L2 cache
cpu1: ITLB 32 4KB entries fully associative, 8 4MB entries fully associative
cpu1: DTLB 32 4KB entries fully associative, 8 4MB entries fully associative
ioapic0 at mainbus0: apid 2 pa 0xfec0, version 21, 24 pins
acpimcfg0 at acpi0 addr 0xe000, bus 0-64
acpihpet0 at acpi0: 14318180 Hz
acpiprt0 at acpi0: bus 0 (PCI0)
acpiprt1 at acpi0: bus 1 (IGFX)
acpiprt2 at acpi0: bus 32 (PCX1)
acpiprt3 at acpi0: bus 63 (PCX2)
acpiprt4 at acpi0: bus -1 (PCX3)
acpiprt5 at acpi0: bus 4 (HUB_)
acpicpu0 at acpi0: PSS
acpicpu1 at acpi0: PSS
acpibtn0 at acpi0: PBTN
acpibtn1 at acpi0: SBTN
cpu0: PowerNow! K8 1596 MHz: speeds: 1600 800 MHz
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 ATI RS690 Host rev 0x00
ppb0 at pci0 dev 1 function 0 ATI RS690 PCIE rev 0x00
pci1 at ppb0 bus 1
radeondrm0 at pci1 dev 5 function 0 ATI Radeon X1250 IGP rev 0x00
drm0 at radeondrm0
radeondrm0: msi
ppb1 at pci0 dev 4 function 0 ATI RS690 PCIE rev 0x00: msi
pci2 at ppb1 bus 32
bge0 at pci2 dev 0 function 0 Broadcom BCM5906M rev 0x02, BCM5906 A2 
(0xc002): msi, address 00:21:5a:63:e5:b5
brgphy0 at bge0 phy 1: BCM5906 10/100baseTX PHY, rev. 0
ppb2 at pci0 dev 5 function 0 ATI RS690 PCIE rev 0x00: msi
pci3 at ppb2 bus 63
bge1 at pci3 dev 0 function 0 Broadcom BCM5906M rev 0x02, BCM5906 A2 
(0xc002): msi, address 00:21:5a:63:ed:86
brgphy1 at bge1 phy 1: BCM5906 10/100baseTX PHY, rev. 0
ahci0 at pci0 dev 18 function 0 ATI SB600 SATA rev 0x00: apic 2 int 22, AHCI 
1.1
ahci0: port 0: 1.5Gb/s
scsibus1 at ahci0: 32 targets
sd0 at scsibus1 targ 0 lun 0: ATA, ST980814AS, 3.CH SCSI3 0/direct fixed 
t10.ATA_ST980814AS_5QY12MCV_
sd0: 76319MB, 512 bytes/sector, 156301488 sectors
ohci0 at pci0 dev 19 function 0 ATI SB600 USB rev 0x00: apic 2 int 16, 
version 1.0, legacy support
ehci0 at pci0 dev 19 function 5 ATI SB600 USB2 rev 0x00: apic 2 int 19
usb0 at ehci0: USB revision 2.0
uhub0 at usb0 ATI EHCI root hub rev 2.00/1.00 addr 1
piixpm0 at pci0 dev 20 function 0 ATI SBx00 SMBus rev 0x14: SMI
iic0 at piixpm0
spdmem0 at iic0 addr 0x50: 2GB DDR2 SDRAM non-parity PC2-5300CL5 SO-DIMM
spdmem1 at iic0 addr 0x51: 2GB DDR2 SDRAM non-parity PC2-5300CL5 SO-DIMM
pciide0 at pci0 dev 20 function 1 ATI SB600 IDE rev 0x00: DMA, channel 0 
configured to native-PCI, channel 1 configured to native-PCI
pciide0: using apic 2 int 16 for native-PCI interrupt
pcib0 at pci0 dev 20 function 3 ATI SB600 ISA rev 0x00
ppb3 at pci0 dev 20 function 4 ATI SB600 PCI rev 0x00
pci4 at ppb3 bus 4
pchb1 at pci0 dev 24 function 0 AMD AMD64 0Fh HyperTransport rev 0x00
pchb2 at pci0 dev 24 function 1 AMD AMD64 0Fh Address Map rev 0x00
pchb3 at pci0 dev 24 function 2 AMD AMD64 0Fh DRAM Cfg rev 0x00
kate0 at pci0 dev 24 function 3 AMD AMD64 0Fh Misc Cfg rev 0x00: core rev 
BH-G2
usb1 at ohci0: USB 

bounds checks in aml_rwgas

2015-03-28 Thread Jonathan Matthew

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 0xfec0, version 21, 24 pins
acpimcfg0 at acpi0 addr 0xe000, bus 0-64
acpihpet0 at acpi0: 14318180 Hz
uvm_fault(0x818c5860, 0x80063000, 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: 0x81a1eab0, 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.?

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 -  1.216
+++ dsdt.c  28 Mar 2015 11:57:07 -
@@ -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 {