>Synopsis: Mounting a NTFS image with bf_bps (bytes per sector) set to 0 causes 
>a fault trap 
>Category: kernel
>Environment:
        System      : OpenBSD 6.1
        Details     : OpenBSD 6.1 (GENERIC) #19: Sat Apr  1 13:42:46 MDT 2017
                         
[email protected]:/usr/src/sys/arch/amd64/compile/GENERIC

        Architecture: OpenBSD.amd64
        Machine     : amd64
>Description:
Mounting a NTFS image with bf_bps (bytes per sector) set to 0 causes a fault 
trap.

kernel: integer divide fault trap, code=0
Stopped at      ntfs_mountfs+0x62e      idivl    %ecx,%eax
ddb> trace
ntfs_mountfs() at ntfs_mountfs+0x62e
ntfs_mount() at ntfs_mount+0x21c
sys_mount() at sys_mount+0x271
syscall() at syscall+0x197
--- syscall (number 21) ---
end of kernel
end trace frame: 0x7f7ffffee601, count: -4
0x6a4de80109a:

# objdump --line --disassemble --reloc ntfs_vfsops.o > ntfs_vfsops.dis
# grep "<ntfs_mountfs>" ntfs_vfsops.dis
00000000000007e0 <ntfs_mountfs>:

0x62e + 0x7e0 = 0xe0e

# cat -n ntfs_vfsops.dis 
<SNIP>
1439  /usr/src/sys/ntfs/ntfs_vfsops.c:317
1440     df0:     0f be c8                movsbl %al,%ecx
1441     df3:     ba 01 00 00 00          mov    $0x1,%edx
1442     df8:     f7 d9                   neg    %ecx
1443     dfa:     d3 e2                   shl    %cl,%edx
1444     dfc:     48 8b 8d e0 fe ff ff    mov    0xfffffffffffffee0(%rbp),%rcx
1445     e03:     0f b7 41 13             movzwl 0x13(%rcx),%eax
1446     e07:     89 c1                   mov    %eax,%ecx
1447     e09:     89 d0                   mov    %edx,%eax
1448     e0b:     c1 fa 1f                sar    $0x1f,%edx
1449     e0e:     f7 f9                   idiv   %ecx
1450     e10:     48 8b 95 e0 fe ff ff    mov    0xfffffffffffffee0(%rbp),%rdx
1451     e17:     89 82 b8 00 00 00       mov    %eax,0xb8(%rdx)
1452     e1d:     e9 2e fc ff ff          jmpq   a50 <ntfs_mountfs+0x270>

# cat -n /usr/src/sys/ntfs/ntfs_vfsops.c
<SNIP>
312        {
313                int8_t cpr = ntmp->ntm_mftrecsz;
314                if( cpr > 0 )
315                        ntmp->ntm_bpmftrec = ntmp->ntm_spc * cpr;
316                else
317                        ntmp->ntm_bpmftrec = (1 << (-cpr)) / ntmp->ntm_bps;

There is no check for !ntmp->ntm_bps

This submission is in response to the Ribose Retrace Challenge. The Bug
Challenge encourages finding bugs in well-known software (OSS / proprietary)
using retrace (https://github.com/riboseinc/retrace).

>How-To-Repeat:
These steps create the header of a NTFS image with bf_bps set to 0, and then
vnconfig is used to create a vnode device and then mount_ntfs to mount the
device causing a fault trap.

1) Construct a NTFS image header (bootfile struct from /usr/src/sys/ntfs/ntfs.h)
# reserved1[3];   /* asm jmp near ... */
printf "\xeb\x48\x90" > ntfs_fs.img
# bf_sysid[8];    /* 'NTFS    ' */
printf "\x4e\x54\x46\x53" >> ntfs_fs.img
printf "\x20\x20\x20\x20" >> ntfs_fs.img
# bf_bps;         /* bytes per sector */
# setting this to 00 will cause a fault trap
printf "\x00\x00" >> ntfs_fs.img
# bf_spc;         /* sectors per cluster */
printf "\x08" >> ntfs_fs.img
# reserved2[7];   /* unused (zeroed) */
printf "\x00\x00\x00\x00\x00\x00\x00" >> ntfs_fs.img
# bf_media;       /* media desc. (0xF8) */
printf "\x78" >> ntfs_fs.img
# reserved3[2];
printf "\x00\x00" >> ntfs_fs.img

2) Mount the image:
vnconfig vnd0 ntfs_fs.img
mkdir /mnt/ntfs
mount_ntfs /dev/vnd0c /mnt/ntfs

>Fix:
A propsed check for !ntmp->ntm_bps:
--- /usr/src/sys/ntfs/ntfs_vfsops.c.bak Mon Aug 21 22:13:43 2017
+++ /usr/src/sys/ntfs/ntfs_vfsops.c     Mon Aug 21 22:14:17 2017
@@ -309,6 +309,12 @@
                goto out;
        }
 
+       if (!ntmp->ntm_bps) {
+               error = EINVAL;
+               DPRINTF("ntfs_mountfs: invalid bytes per sector\n");
+               goto out;
+       }
+
        {
                int8_t cpr = ntmp->ntm_mftrecsz;
                if( cpr > 0 )



dmesg:
OpenBSD 6.1 (GENERIC) #19: Sat Apr  1 13:42:46 MDT 2017
    [email protected]:/usr/src/sys/arch/amd64/compile/GENERIC
real mem = 117374976 (111MB)
avail mem = 109367296 (104MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.5 @ 0xe1000 (10 entries)
bios0: vendor innotek GmbH version "VirtualBox" date 12/01/2006
bios0: innotek GmbH VirtualBox
acpi0 at bios0: rev 2
acpi0: sleep states S0 S5
acpi0: tables DSDT FACP APIC SSDT
acpi0: wakeup devices
acpitimer0 at acpi0: 3579545 Hz, 32 bits
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: Intel(R) Core(TM) i7-4850HQ CPU @ 2.30GHz, 2294.99 MHz
cpu0: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,SSE3,PCLMUL,MWAIT,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,RDRAND,NXE,RDTSCP,LONG,LAHF,ABM,ITSC
cpu0: 256KB 64b/line 8-way L2 cache
cpu0: TSC frequency 2294990010 Hz
cpu0: smt 0, core 0, package 0
mtrr: CPU supports MTRRs but not enabled by BIOS
cpu0: apic clock running at 999MHz
cpu0: mwait min=64, max=64
ioapic0 at mainbus0: apid 1 pa 0xfec00000, version 20, 24 pins
acpiprt0 at acpi0: bus 0 (PCI0)
acpicpu0 at acpi0: C1(@1 halt!)
"PNP0303" at acpi0 not configured
"PNP0F03" at acpi0 not configured
acpibat0 at acpi0: BAT0 model "1" serial 0 type VBOX oem "innotek"
acpiac0 at acpi0: AC unit online
acpivideo0 at acpi0: GFX0
pci0 at mainbus0 bus 0
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, 1024MB, 2097152 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> ATAPI 5/cdrom 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: apic 1 int 19, address 
08:00:27:c5:40:5d
"InnoTek VirtualBox Guest Service" rev 0x00 at pci0 dev 4 function 0 not 
configured
ohci0 at pci0 dev 6 function 0 "Apple Intrepid USB" rev 0x00: apic 1 int 22, 
version 1.0
piixpm0 at pci0 dev 7 function 0 "Intel 82371AB Power" rev 0x08: apic 1 int 23
iic0 at piixpm0
ehci0 at pci0 dev 11 function 0 "Intel 82801FB USB" rev 0x00: apic 1 int 19
usb0 at ehci0: USB revision 2.0
uhub0 at usb0 configuration 1 interface 0 "Intel EHCI root hub" rev 2.00/1.00 
addr 1
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
usb1 at ohci0: USB revision 1.0
uhub1 at usb1 configuration 1 interface 0 "Apple OHCI root hub" rev 1.00/1.00 
addr 1
vscsi0 at root
scsibus2 at vscsi0: 256 targets
softraid0 at root
scsibus3 at softraid0: 256 targets
root on wd0a (a7053a0793dc5865.a) swap on wd0b dump on wd0b

Reply via email to