| Debugging information: |
The bug has been found using the BSD version of fsfuzzer on a
FreeBSD 6.1 installation with a kernel
compiled from sources available in ftp.freebsd.org. No operation except mount itself, is necessary to
trigger the bug. The architecture used to conduct the tests is IA32/x86.
# uname -a
FreeBSD freebsdvm.info-pull.com 6.1-RELEASE FreeBSD 6.1-RELEASE #1: Thu Nov 2 21:15:59 UTC 2006
root@freebsdvm.info-pull.com:/usr/obj/usr/src/sys/GENERIC i386
It's been observed that different conditions appear when filesystem MAC labeling
is enabled, triggering the bug via different callbacks.
The following 'output' is a detailed analysis of the bug using kgdb and the crash dump with a kernel
image containing debug symbols:
[root@freebsdvm /sys/i386/include]# kgdb -d /usr/crash/ -n 1 /usr/obj/usr/src/sys/GENERIC/kernel.debug
[GDB will not be able to debug user-mode threads: /usr/lib/libthread_db.so: Undefined symbol "ps_pglobal_lookup"]
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-marcel-freebsd".
Unread portion of the kernel message buffer:
: mount pending error: blocks 37999121861655040 files 0
panic: kmem_malloc(76681216): kmem_map too small: 10866688 total allocated
Uptime: 2h3m18s
Dumping 255 MB (3 chunks)
chunk 0: 1MB (159 pages) ... ok
chunk 1: 254MB (65008 pages) 238 222 206 190 174 158 142 126 110 94 78 62 46 30 14 ... ok
chunk 2: 1MB (256 pages)
#0 doadump () at pcpu.h:165
165 __asm __volatile("movl %%fs:0,%0" : "=r" (td));
(kgdb) back
#0 doadump () at pcpu.h:165
#1 0xc064dee1 in boot (howto=260) at /usr/src/sys/kern/kern_shutdown.c:402
#2 0xc064e178 in panic (fmt=0xc08baffd ) at /usr/src/sys/kern/kern_shutdown.c:558
#3 0xc07bc3a1 in kmem_malloc (map=0xc10430c0, size=76681216, flags=2) at /usr/src/sys/vm/vm_kern.c:299
#4 0xc07b3c6e in page_alloc (zone=0x0, bytes=76681216, pflag=0x0, wait=2) at /usr/src/sys/vm/uma_core.c:958
#5 0xc07b5fc7 in uma_large_malloc (size=76681216, wait=2) at /usr/src/sys/vm/uma_core.c:2702
#6 0xc0643815 in malloc (size=76681216, mtp=0xc0952460, flags=2) at /usr/src/sys/kern/kern_malloc.c:329
#7 0xc07a0b66 in ffs_mountfs (devvp=0xc2776220, mp=0xc2319400, td=0xc233c600) at /usr/src/sys/ufs/ffs/ffs_vfsops.c:681
#8 0xc079fd29 in ffs_mount (mp=0xc2319400, td=0xc233c600) at /usr/src/sys/ufs/ffs/ffs_vfsops.c:358
#9 0xc069f550 in vfs_domount (td=0xc233c600, fstype=0xc2793990 "\002", fspath=0xc231dc80 "/mnt/test", fsflags=0,
fsdata=0xc231dbe0) at /usr/src/sys/kern/vfs_mount.c:882
#10 0xc069edae in vfs_donmount (td=0xc233c600, fsflags=0, fsoptions=0xd0a86c04) at /usr/src/sys/kern/vfs_mount.c:640
#11 0xc06a15bc in kernel_mount (ma=0xc231d6c0, flags=0) at pcpu.h:162
#12 0xc079fdc5 in ffs_cmount (ma=0xc231d6c0, data=0x0, flags=0, td=0xc233c600) at /usr/src/sys/ufs/ffs/ffs_vfsops.c:385
#13 0xc069ef92 in mount (td=0xc233c600, uap=0xd0a86d04) at /usr/src/sys/kern/vfs_mount.c:703
#14 0xc08420ab in syscall (frame=
{tf_fs = 59, tf_es = 59, tf_ds = 59, tf_edi = 134523775, tf_esi = -1077941580, tf_ebp = -1077944168,
tf_isp = -794268316, tf_ebx = -1077944112, tf_edx = 0, tf_ecx = 1, tf_eax = 21, tf_trapno = 12,
tf_err = 2, tf_eip = 671845899, tf_cs = 51, tf_eflags = 582,
tf_esp = -1077944324, tf_ss = 59}) at /usr/src/sys/i386/i386/trap.c:981
#15 0xc0830cef in Xint0x80_syscall () at /usr/src/sys/i386/i386/exception.s:200
#16 0x00000033 in ?? ()
Previous frame inner to this frame (corrupt stack?)
(kgdb) info registers
eax 0x0 0
ecx 0x0 0
edx 0x0 0
ebx 0xc232a080 -1036869504
esp 0xd0a86840 0xd0a86840
ebp 0xd0a86848 0xd0a86848
esi 0x0 0
edi 0x4 4
eip 0xc064da16 0xc064da16
eflags 0x0 0
cs 0x0 0
ss 0x0 0
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(kgdb) list 550
545 static int
546 ffs_mountfs(devvp, mp, td)
547 struct vnode *devvp;
548 struct mount *mp;
549 struct thread *td;
550 {
(...)
(kgdb)
557 int error, i, blks, size, ronly; <------
(kgdb) list *0xc07a0b66
0xc07a0b66 is in ffs_mountfs (/usr/src/sys/ufs/ffs/ffs_vfsops.c:681).
676 size = fs->fs_cssize; <--------- 2048
677 blks = howmany(size, fs->fs_fsize); <-- = 76681236 (fs->fs_fsize = 2048)
((size)+(fs->fs_fsize)-1/(fs->fs_fsize))
------------------------------ sys/ufs/ffs/fs.h
252 #define howmany(x, y) (((x)+((y)-1))/(y))
------------------------------ sys/ufs/ffs/fs.h
678 if (fs->fs_contigsumsize > 0)
679 size += fs->fs_ncg * sizeof(int32_t); <-- fs->fs_ncg = 15335428, int32_t = 4
680 size += fs->fs_ncg * sizeof(u_int8_t); <-- fs->fs_ncg = 15335428, u_int8_t = 1
681 space = malloc((u_long)size, M_UFSMNT, M_WAITOK); <--------- to #6
682 fs->fs_csp = space;
683 for (i = 0; i < blks; i += fs->fs_frag) {
684 size = fs->fs_bsize;
685 if (i + fs->fs_frag > blks)
(kgdb) printf "%d %d\n", sizeof(u_int8_t), sizeof(int32_t)
1 4
(kgdb) list 589,611
589 bp = NULL;
590 ump = NULL;
591 fs = NULL;
592 sblockloc = 0;
593 /*
594 * Try reading the superblock in each of its possible locations.
595 */
596 for (i = 0; sblock_try[i] != -1; i++) {
597 if ((error = bread(devvp, sblock_try[i] / DEV_BSIZE, SBLOCKSIZE,
------------------------------- sys/ufs/ffs/fs.h
68 #define SBLOCK_FLOPPY 0
69 #define SBLOCK_UFS1 8192
70 #define SBLOCK_UFS2 65536
71 #define SBLOCK_PIGGY 262144
72 #define SBLOCKSIZE 8192
73 #define SBLOCKSEARCH \
74 { SBLOCK_UFS2, SBLOCK_UFS1, SBLOCK_FLOPPY, SBLOCK_PIGGY, -1 }
------------------------------- sys/ufs/ffs/fs.h
598 cred, &bp)) != 0)
599 goto out;
600 fs = (struct fs *)bp->b_data; <------------ fs assigned to bp
(from bread(devpp at 0xc2776220))
601 sblockloc = sblock_try[i];
602 if ((fs->fs_magic == FS_UFS1_MAGIC ||
603 (fs->fs_magic == FS_UFS2_MAGIC &&
604 (fs->fs_sblockloc == sblockloc ||
605 (fs->fs_old_flags & FS_FLAGS_UPDATED) == 0))) &&
606 fs->fs_bsize <= MAXBSIZE && <-
607 fs->fs_bsize >= sizeof(struct fs)) <-
608 break;
609 brelse(bp);
610 bp = NULL; <-
611 }
------------------------------- sys/ufs/ffs/fs.h
360 /*
361 * Filesystem identification
362 */
363 #define FS_UFS1_MAGIC 0x011954 /* UFS1 fast filesystem magic number */
364 #define FS_UFS2_MAGIC 0x19540119 /* UFS2 fast filesystem magic number */
-------------------------------- sys/ufs/ffs/fs.h
(kgdb) x/6 0xc2776220 <---- ptr to devpp
0xc2776220: "\004"
0xc2776222: ""
0xc2776223: ""
0xc2776224: "+#\212� \025\221�\200\2076�"
0xc2776231: "�0�"
0xc2776235: ""
(kgdb) select-frame 7
(kgdb) info locals
ump = (struct ufsmount *) 0xc23ca400
bp = (struct buf *) 0x0
fs = (struct fs *) 0xc2470800
dev = (struct cdev *) 0xc237ad00
space = (void *) 0xc233c600
sblockloc = 65536
error = 0
i = 0
blks = 1
size = 76679188
ronly = 0
lp = (int32_t *) 0x0
cred = (struct ucred *) 0xc25c0680
cp = (struct g_consumer *) 0xc232b300
(kgdb) print fs->fs_volname
$22 = "AA�BCCDD\000\000\000\000\000\000\000\210", '\0'
(kgdb) print fs->fs_magic
$24 = 424935705
(kgdb) printf "%p\n", 424935705
0x19540119 <------ = FS_UFS2_MAGIC
|