> Synopsis: -1 idx in wscons ioctl causes panic
> Category: kernel
> Environment:
System : OpenBSD 6.6
Details : OpenBSD 6.6 (CUSTOM) #1: Sun Apr 26 00:27:17 CDT 2020
[email protected]:/usr/src/sys/arch/i386/compile/CUSTOM
Architecture: OpenBSD.i386
Machine : i386
> Description:
The WSDISPLAYIO_GETSCREENTYPE ioctl idx is not range checked for
negatives, so
it gets a kernel page fault in strncpy.
> How-To-Repeat:
Run this program as root to get a kernel panic:
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <dev/wscons/wsconsio.h>
#include <unistd.h>
#include <sys/ioctl.h>
int main(int argc, char **argv) {
int fd = open("/dev/ttyC0", O_RDONLY);
if (fd < 0) {
perror("fopen tty");
return -1;
}
// invalid idx of -1 causes a kernel panic
struct wsdisplay_screentype type={.idx=-1};
if (-1 == ioctl(fd, WSDISPLAYIO_GETSCREENTYPE, &type)) {
perror("WSDISPLAYIO_GETSCREENTYPE");
return -1;
}
printf("WSDISPLAYIO_GETSCREENTYPE:\n");
printf("idx :%i\n", type.idx);
printf("nidx:%i\n", type.nidx);
printf("name:%s\n", type.name);
printf("dims:%i x %i\n", type.ncols, type.nrows);
printf("font:%i x %i\n", type.fontwidth, type.fontheight);
close(fd);
}
> Fix:
in /usr/src/sys/dev/wscons/wsdisplay.c, correct the EINVAL range check
with an || < 0, unsigned cast, or change the type of idx to unsigned:
case WSDISPLAYIO_GETSCREENTYPE:
#define d ((struct wsdisplay_screentype *)data)
if (d->idx >= sc->sc_scrdata->nscreens)
return(EINVAL);
d->nidx = sc->sc_scrdata->nscreens;
strncpy(d->name, sc->sc_scrdata->screens[d->idx]->name,
WSSCREEN_NAME_SIZE);
d->ncols = sc->sc_scrdata->screens[d->idx]->ncols;
d->nrows = sc->sc_scrdata->screens[d->idx]->nrows;
d->fontwidth = sc->sc_scrdata->screens[d->idx]->fontwidth;
d->fontheight = sc->sc_scrdata->screens[d->idx]->fontheight;
return (0);
#undef d
dmesg:
OpenBSD 6.6 (CUSTOM) #1: Sun Apr 26 00:27:17 CDT 2020
[email protected]:/usr/src/sys/arch/i386/compile/CUSTOM
real mem = 1073168384 (1023MB)
avail mem = 1037930496 (989MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: date 06/23/99, BIOS32 rev. 0 @ 0xfda00, SMBIOS rev.
2.5 @ 0xe1000 (10 entries)
bios0: vendor innotek GmbH version "VirtualBox" date 12/01/2006
bios0: innotek GmbH VirtualBox
acpi0 at bios0: ACPI 4.0
acpi0: sleep states S0 S5
acpi0: tables DSDT FACP SSDT
acpi0: wakeup devices
acpitimer0 at acpi0: 3579545 Hz, 32 bits
tc_init(acpitimer0,ffffffff,3579545,1000)
acpiprt0 at acpi0: bus 0 (PCI0)
"PNP0A03" at acpi0 not configured
acpiac0 at acpi0: AC unit online
acpivideo0 at acpi0: GFX0
bios0: ROM list: 0xc0000/0x8000 0xe2000/0xd400
cpu0 at mainbus0: (uniprocessor)
cpu0: AMD Eng Sample: 100-000000163-01_43/29_Y ("AuthenticAMD"
686-class, 512KB L2 cache) 2.91 GHz, 17-31-00
cpu0:
FPU,V86,DE,PSE,TSC,MSR,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,RDRAND,MMXX,FFXSR,RDTSCP,LAHF,AMCR8,ABM,SSE4A,MASSE,3DNOWP,ITSC,FSGSBASE,AVX2,RDSEED,CLFLUSHOPT
mtrr: CPU supports MTRRs but not enabled by BIOS
cpu0: mwait min=64, max=64
pci0 at mainbus0 bus 0: configuration mode 1 (bios)
pchb0 at pci0 dev 0 function 0 "Intel 82441FX" rev 0x02
pcib0 at pci0 dev 1 function 0 "Intel 82371SB ISA" rev 0x00
pciide0 at pci0 dev 1 function 1 "Intel 82371AB IDE" rev 0x01: DMA,
channel 0 configured to compatibility, channel 1 configured to
compatibility
wd0 at pciide0 channel 0 drive 0: <VBOX HARDDISK>
wd0: 128-sector PIO, LBA, 16384MB, 33554432 sectors
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 2
atapiscsi0 at pciide0 channel 1 drive 0
scsibus1 at atapiscsi0: 2 targets
cd0 at scsibus1 targ 0 lun 0: <VBOX, CD-ROM, 1.0> removable
cd0(pciide0:1:0): using PIO mode 4, Ultra-DMA mode 2
vga1 at pci0 dev 2 function 0 "InnoTek VirtualBox Graphics Adapter" rev
0x00
wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
em0 at pci0 dev 3 function 0 "Intel 82540EM" rev 0x02: irq 9, address
08:00:27:a8:9a:1d
"InnoTek VirtualBox Guest Service" rev 0x00 at pci0 dev 4 function 0 not
configured
auich0 at pci0 dev 5 function 0 "Intel 82801AA AC97" rev 0x01: irq 11,
ICH
ac97: codec id 0x83847600 (SigmaTel STAC9700)
audio0 at auich0
ohci0 at pci0 dev 6 function 0 "Apple Intrepid USB" rev 0x00: irq 10,
version 1.0
piixpm0 at pci0 dev 7 function 0 "Intel 82371AB Power" rev 0x08: irq 9
iic0 at piixpm0
isa0 at pcib0
isadma0 at isa0
pckbc0 at isa0 port 0x60/5 irq 1 irq 12
pckbd0 at pckbc0 (kbd slot)
wskbd0 at pckbd0: console keyboard, using wsdisplay0
pms0 at pckbc0 (aux slot)
wsmouse0 at pms0 mux 0
pcppi0 at isa0 port 0x61
spkr0 at pcppi0
npx0 at isa0 port 0xf0/16: reported by CPUID; using exception 16
usb0 at ohci0: USB revision 1.0
uhub0 at usb0 configuration 1 interface 0 "Apple OHCI root hub" rev
1.00/1.00 addr 1
tc_init(i8254,ffffffff,1193182,0)
vscsi0 at root
scsibus2 at vscsi0: 256 targets
softraid0 at root
scsibus3 at softraid0: 256 targets
root on wd0a (1cd2ea98eecfc574.a) swap on wd0b dump on wd0b
WARNING: / was not properly unmounted
usbdevs:
Controller /dev/usb0:
addr 01: 106b:0000 Apple, OHCI root hub
full speed, self powered, config 1, rev 1.00
driver: uhub0