MOKB-04-11-2006

Bug details
Title: Solaris 10 UFS filesystem alloccgblk denial of service
Description: The UFS filesystem handling code of the Solaris 10 kernel fails to properly handle corrupted data structures, leading to an exploitable denial of service issue and potential loss of data or corruption of the local UFS filesystems, due to memory corruption.
Author/Contributor:
References:
Proof of concept or exploit: The following filesystem image can be used to reproduce the bug: MOKB-04-11-2006.img.gz
Use a lofi device to mount it: gunzip MOKB-04-11-2006.img.gz && lofiadm -a MOKB-04-11-2006.img /dev/lofi/2 && mount -F ufs /dev/lofi/2 /mnt/test
Debugging information:

The bug has been found using the BSD version of fsfuzzer (modified for compatibility with Solaris) on a Sun Solaris 10 installation, up to date with all security patches as of 04-11-2006. No operation except mount itself, is necessary to trigger the bug. The architecture used to conduct the tests is IA32/x86. This issue might be present in earlier versions.

bash-3.00# uname -a
SunOS solaris10vm 5.10 Generic_118855-19 i86pc i386 i86pc
				

I'm not used to the Solaris kernel internals, thus I could have missed some information. Output below is a kmdb session on the generated crash dump. Possibly this issue will be subject of updates.

bash-3.00# mdb /var/crash/solaris10vm/unix.0  /var/crash/solaris10vm/vmcore.0
Loading modules: [ unix krtld genunix specfs dtrace ufs ip sctp usba fctl nca lofs audiosup random nfs cpc fcip crypto ptm sppp ]
lofi0 is /pseudo/lofi@0
> ::msgbuf
panic[cpu0]/thread=ffffffff9011ce60:
BAD TRAP: type=e (#pf Page fault) rp=fffffe80005a7410 addr=ffffffff8fde3c84


mount:
#pf Page fault
Bad kernel fault at addr=0xffffffff8fde3c84
pid=1221, pc=0xfffffffffbb1035d, sp=0xfffffe80005a7500, eflags=0x10206
cr0: 8005003b cr4: 6b0
cr2: ffffffff8fde3c84 cr3: 8be5000 cr8: c
        rdi: ffffffff9c894000 rsi: ffffffff9c89eb08 rdx: ffffffff88ee3c80
        rcx:               b5  r8:                1  r9: fffffe80005a7680
        rax:          6f00000 rbx:               b5 rbp: fffffe80005a7570
        r10:               78 r11: fffffffffbcc5940 r12:         361005a8
        r13: ffffffff9c894000 r14: ffffffff93093b10 r15: ffffffff9c89e800
        fsb: ffffffff80000000 gsb: fffffffffbc24060  ds:               43
         es:               43  fs:                0  gs:              1c3
        trp:                e err:                2 rip: fffffffffbb1035d
         cs:               28 rfl:            10206 rsp: fffffe80005a7500
         ss:               30

fffffe80005a7320 unix:real_mode_end+58d1 ()
fffffe80005a7400 unix:trap+d77 ()
fffffe80005a7410 unix:_cmntrap+13f ()
fffffe80005a7570 ufs:alloccgblk+dd ()
fffffe80005a75f0 ufs:alloccg+3a3 ()
fffffe80005a7640 ufs:hashalloc+42 ()
fffffe80005a76b0 ufs:alloc+10b ()
fffffe80005a7760 ufs:lufs_alloc+d9 ()
fffffe80005a77f0 ufs:lufs_enable+24f ()
fffffe80005a7840 ufs:ufs_fiologenable+53 ()
fffffe80005a7db0 ufs:ufs_ioctl+4bd ()
fffffe80005a7de0 genunix:fop_ioctl+1a ()
fffffe80005a7ec0 genunix:ioctl+ac ()
fffffe80005a7f10 unix:sys_sysenter+14e ()

syncing file systems...
(...)
 done (not all i/o completed)
dumping to /dev/dsk/c0d0s1, offset 108593152, content: kernel
> ::cpuinfo
 ID ADDR        FLG NRUN BSPL PRI RNRN KRNRN SWITCH THREAD      PROC
  0 fffffffffbc2bb60  1b    1    0  49   no    no t-0    ffffffff9011ce60 mount
> 0xffffffff8fde3c84::whatis
ffffffff8fde3c84 is ffffffff8fd6e000+75c84 freed from heap vmem arena
> $C
fffffe80005a7570 alloccgblk+0xdd()
fffffe80005a75f0 alloccg+0x3a3()
fffffe80005a7640 hashalloc+0x42()
fffffe80005a76b0 alloc+0x10b()
fffffe80005a7760 lufs_alloc+0xd9()
fffffe80005a77f0 lufs_enable+0x24f()
fffffe80005a7840 ufs_fiologenable+0x53()
fffffe80005a7db0 ufs_ioctl+0x4bd()
fffffe80005a7de0 fop_ioctl+0x1a()
fffffe80005a7ec0 ioctl+0xac()
fffffe80005a7f10 _sys_sysenter_post_swapgs+0x14b()
> fffffe80005a7410::bufctl
ADDR             BUFADDR          TIMESTAMP    THREAD           CALLER
fffffe80005a7410 fffffffffbb1035d ffffffff88ee3c80 00000000000000b5 apic_cr8pri
> ffffffff8fde3c84::bufctl
ADDR             BUFADDR          TIMESTAMP    THREAD           CALLER
mdb: couldn't read bufctl at ffffffff8fde3c84: no mapping for address
> 0xfffffffffbb1035d::dis
alloccgblk+0xae:                jne    +0x352   
alloccgblk+0xb4:                movq   -0x58(%rbp),%rsi
alloccgblk+0xb8:                movq   %rbx,%rdx
alloccgblk+0xbb:                movq   %r13,%rdi
alloccgblk+0xbe:                call   +0xbf22  
alloccgblk+0xc3:                decl   0x1c(%r15)
alloccgblk+0xc7:                decl   0xc4(%r13)
alloccgblk+0xce:                movq   0x2d8(%r13),%rdx
alloccgblk+0xd5:                movslq 0xc(%r15),%rax
alloccgblk+0xd9:                shlq   $0x4,%rax
alloccgblk+0xdd:                decl   0x4(%rax,%rdx)
alloccgblk+0xe1:                movslq 0x7c(%r13),%rax
alloccgblk+0xe5:                movslq 0xac(%r13),%rdx
alloccgblk+0xec:                imulq  -0x48(%rbp),%rax
alloccgblk+0xf1:                movl   0x4(%r15),%r9d
alloccgblk+0xf5:                movq   %rdx,%rbx
alloccgblk+0xf8:                cqtd
alloccgblk+0xfa:                idivq  %rbx
alloccgblk+0xfd:                cmpl   $0x90255,%r9d
alloccgblk+0x104:               movl   %eax,%r8d
alloccgblk+0x107:               je     +0x38a   
> ffffffff88ee3c80::whatis -a
ffffffff88ee3c80 is ffffffff88ee3c80+0, bufctl ffffffff8a5e9ab8 allocated from kmem_alloc_1152
ffffffff88ee3c80 is ffffffff88ee2000+1c80, allocated from kmem_va_12288
ffffffff88ee3c80 is ffffffff88ee2000+1c80 (vmem_seg ffffffff8a940488) from kmem_default vmem arena
ffffffff88ee3c80 is ffffffff88ee2000+1c80 (vmem_seg ffffffff84c439b0) from kmem_va vmem arena
ffffffff88ee3c80 is ffffffff88ee2000+1c80 (vmem_seg ffffffff88bdfcb0) from heap vmem arena
> ffffffff88ee3c80::kmalog <------------- %rdx

T-0.030126448  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_alloc_debug+0x1fa
         kmem_cache_alloc+0x6f
         kmem_alloc+0x70
         ufs_getsummaryinfo+0x3c
         mountfs+0x3d8
         ufs_mount+0x301
         fsop_mount+0xa
         domount+0x4d3
         mount+0x105
         syscall_ap+0x97

T-0.030594756  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_free_debug+0xf4
         kmem_cache_free+0x43
         kmem_free+0x14b
         pn_free+0x19
         lookuppnvp+0x52a
         lookuppnat+0xf9
         lookupnameat+0x86
         lookupname+0xc
         ufs_mount+0x12f
         fsop_mount+0xa
         domount+0x4d3
         mount+0x105
         syscall_ap+0x97

T-0.030597607  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_alloc_debug+0x1fa
         kmem_cache_alloc+0x6f
         kmem_alloc+0x70
         pn_alloc+0x18
         lookuppnvp+0x4cd
         lookuppnat+0xf9
         lookupnameat+0x86
         lookupname+0xc
         ufs_mount+0x12f
         fsop_mount+0xa
         domount+0x4d3
         mount+0x105
         syscall_ap+0x97

T-0.032017376  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_free_debug+0xf4
         kmem_cache_free+0x43
         kmem_free+0x14b
         pn_free+0x19
         domount+0xb7a
         mount+0x105
         syscall_ap+0x97

T-0.032021592  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_alloc_debug+0x1fa
         kmem_cache_alloc+0x6f
         kmem_alloc+0x70
         pn_alloc+0x18
         domount+0xaca
         mount+0x105
         syscall_ap+0x97

T-0.038007128  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_free_debug+0xf4
         kmem_cache_free+0x43
         kmem_free+0x14b
         pn_free+0x19
         lookuppnvp+0x52a
         lookuppnat+0xf9
         lookuppn+0xc
         exec_common+0x171
         exece+9

T-0.038009189  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_alloc_debug+0x1fa
         kmem_cache_alloc+0x6f
         kmem_alloc+0x70
         pn_alloc+0x18
         lookuppnvp+0x4cd
         lookuppnat+0xf9
         lookuppn+0xc
         exec_common+0x171
         exece+9

T-0.046739556  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_free_debug+0xf4
         kmem_cache_free+0x43
         kmem_free+0x14b
         pn_free+0x19
         lookuppnvp+0x52a
         lookuppnat+0xf9
         lookuppn+0xc
         exec_common+0x171
         exece+9

T-0.046743141  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_alloc_debug+0x1fa
         kmem_cache_alloc+0x6f
         kmem_alloc+0x70
         pn_alloc+0x18
         lookuppnvp+0x4cd
         lookuppnat+0xf9
         lookuppn+0xc
         exec_common+0x171
         exece+9

T-4.580874334  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_free_debug+0xf4
         kmem_cache_free+0x43
         kmem_free+0x14b
         pn_free+0x19
         domount+0xb7a
         mount+0x105
         syscall_ap+0x97

T-4.580878315  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_alloc_debug+0x1fa
         kmem_cache_alloc+0x6f
         kmem_alloc+0x70
         pn_alloc+0x18
         domount+0xaca
         mount+0x105
         syscall_ap+0x97

T-4.588163438  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_free_debug+0xf4
         kmem_cache_free+0x43
         kmem_free+0x14b
         pn_free+0x19
         lookuppnvp+0x52a
         lookuppnat+0xf9
         lookuppn+0xc
         exec_common+0x171
         exece+9

T-4.588165608  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_alloc_debug+0x1fa
         kmem_cache_alloc+0x6f
         kmem_alloc+0x70
         pn_alloc+0x18
         lookuppnvp+0x4cd
         lookuppnat+0xf9
         lookuppn+0xc
         exec_common+0x171
         exece+9

T-4.611465595  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_free_debug+0xf4
         kmem_cache_free+0x43
         kmem_free+0x14b
         pn_free+0x19
         lookuppnvp+0x52a
         lookuppnat+0xf9
         lookuppn+0xc
         exec_common+0x171
         exece+9

T-4.611469176  addr=ffffffff88ee3c80  kmem_alloc_1152
         kmem_cache_alloc_debug+0x1fa
         kmem_cache_alloc+0x6f
         kmem_alloc+0x70
         pn_alloc+0x18
         lookuppnvp+0x4cd
         lookuppnat+0xf9
         lookuppn+0xc
         exec_common+0x171
         exece+9
> fffffe80005a7570::kmem_verify
mdb: failed to allocate 18446742424448038720 bytes -- terminating