| Debugging information: |
The bug has been found using the Linux version of fsfuzzer
on a Fedora Core 6 installation, with up to date packages as of
14-11-2006. No operation except mount itself is necessary to trigger the bug.
The architecture used to conduct the tests is IA32/x86, SMP enabled. As of 2.6.18, gfs2 is not supported by
the mainline kernel (not yet merged).
[root@fedoravm ~]# uname -a
Linux fedoravm 2.6.18-1.2798.fc6 #1 SMP Mon Oct 16 14:37:32 EDT 2006 i686 i686 i386 GNU/Linux
GFS2 (built Oct 16 2006 14:39:08) installed
BUG: unable to handle kernel NULL pointer dereference at virtual address 000002a c
printing eip:
d0be45a9
*pde = 00000000
Oops: 0000 [#1]
SMP
last sysfs file: /block/loop3/range
Modules linked in: lock_nolock gfs2 hfs loop ipv6 sunrpc ip_conntrack_netbios_ns ipt_REJECT
xt_state ip_conntrack nfnetlink xt_tcpudp iptable_filter ip_tables x _tables
video sbs i2c_ec button battery asus_acpi ac parport_pc lp parport snd_ens1371 g ameport snd_rawmidi
snd_ac97_codec snd_ac97_bus snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq sg snd_seq_device
snd_pcm_oss snd_mixer_oss snd_pcm v mxnet(U) snd_timer floppy i2c_piix4 snd pcnet32 i2c_core ide_cd cdrom
soundcore mii serio_raw snd_page_alloc pcspkr dm_snapshot dm_zero dm_mirror dm_mod ext3 jbd mp tspi
scsi_transport_spi mptscsih sd_mod scsi_mod mptbase
CPU: 0
EIP: 0060:[] Tainted: P VLI
EFLAGS: 00010207 (2.6.18-1.2798.fc6 #1)
EIP is at init_journal+0x57/0x3f5 [gfs2]
eax: 00000000 ebx: 00000000 ecx: 00000001 edx: 00000000
esi: ca9f3000 edi: ca82b028 ebp: ca9f3000 esp: ca87bc94
ds: 007b es: 007b ss: 0068
Process mount.gfs2 (pid: 1929, ti=ca87b000 task=cfe232c0 task.ti=ca87b000)
Stack: ca9f3000 d0bef9c0 cfe232c0 ca82b2d8 caae352c caae352c d0bd9ae2 caae352c
00000000 0000004d ca9f3000 00000000 00000003 ca82b1b4 00000003 ca82b028
d0bdba52 ca82b2d8 00000001 ca87bce4 caae352c 00000000 ca9f3000 ca82b028
Call Trace:
[] init_inodes+0x54/0x1da [gfs2]
[] fill_super+0x50e/0x632 [gfs2]
[] get_sb_bdev+0xce/0x11c
[] gfs2_get_sb+0x21/0x3e [gfs2]
[] vfs_kern_mount+0x83/0xf6
[] do_kern_mount+0x2d/0x3e
[] do_mount+0x5fa/0x66d
[] sys_mount+0x77/0xae
[] syscall_call+0x7/0xb
DWARF2 unwinder stuck at syscall_call+0x7/0xb
Leftover inexact backtrace:
=======================
Code: 76 29 8d 85 9c 08 00 00 c7 44 24 08 00 00 00 00 89 44 24 04 c7 04 24 2a 21 bf d0 e8 f0 11 84 ef 8b
bd 20 04 00 00 e9 94 03 00 00 <8b> 80 ac 02 00 00 90 0f ba 68 08
02 8d 54 24 14 89 e8 e8 92 89
EIP: [] init_journal+0x57/0x3f5 [gfs2] SS:ESP 0068:ca87bc94
http://people.redhat.com/mingo/gfs2-patches/patches/gfs2-04.patch
+static int init_journal(struct gfs2_sbd *sdp, int undo)
+{
+ struct gfs2_holder ji_gh;
+ struct task_struct *p;
+ int jindex = 1;
+ int error = 0;
+
+ if (undo) {
+ jindex = 0;
+ goto fail_recoverd;
+ }
+
+ error = gfs2_lookup_simple(sdp->sd_master_dir, "jindex",
+ &sdp->sd_jindex);
+ if (error) {
+ fs_err(sdp, "can't lookup journal index: %d\n", error);
+ return error;
+ }
+ set_bit(GLF_STICKY, &sdp->sd_jindex->i_gl->gl_flags);
+
+ /* Load in the journal index special file */
+
+ error = gfs2_jindex_hold(sdp, &ji_gh);
+ if (error) {
+ fs_err(sdp, "can't read journal index: %d\n", error);
+ goto fail;
+ }
+
+ error = -EINVAL;
+ if (!gfs2_jindex_size(sdp)) {
+ fs_err(sdp, "no journals!\n");
+ goto fail_jindex;
+ }
+
+ if (sdp->sd_args.ar_spectator) {
+ sdp->sd_jdesc = gfs2_jdesc_find(sdp, 0);
+ sdp->sd_log_blks_free = sdp->sd_jdesc->jd_blocks;
+ } else {
+ if (sdp->sd_lockstruct.ls_jid >= gfs2_jindex_size(sdp)) {
+ fs_err(sdp, "can't mount journal #%u\n",
+ sdp->sd_lockstruct.ls_jid);
+ fs_err(sdp, "there are only %u journals (0 - %u)\n",
+ gfs2_jindex_size(sdp),
+ gfs2_jindex_size(sdp) - 1);
+ goto fail_jindex;
+ }
+ sdp->sd_jdesc = gfs2_jdesc_find(sdp, sdp->sd_lockstruct.ls_jid);
+
+ error = gfs2_glock_nq_num(sdp,
+ sdp->sd_lockstruct.ls_jid,
+ &gfs2_journal_glops,
+ LM_ST_EXCLUSIVE, LM_FLAG_NOEXP,
+ &sdp->sd_journal_gh);
+ if (error) {
+ fs_err(sdp, "can't acquire journal glock: %d\n", error);
+ goto fail_jindex;
+ }
+
+ error = gfs2_glock_nq_init(sdp->sd_jdesc->jd_inode->i_gl,
+ LM_ST_SHARED,
+ LM_FLAG_NOEXP | GL_EXACT,
+ &sdp->sd_jinode_gh);
+ if (error) {
+ fs_err(sdp, "can't acquire journal inode glock: %d\n",
+ error);
+ goto fail_journal_gh;
+ }
+
+ error = gfs2_jdesc_check(sdp->sd_jdesc);
+ if (error) {
+ fs_err(sdp, "my journal (%u) is bad: %d\n",
+ sdp->sd_jdesc->jd_jid, error);
+ goto fail_jinode_gh;
+ }
+ sdp->sd_log_blks_free = sdp->sd_jdesc->jd_blocks;
+ }
+
+ if (sdp->sd_lockstruct.ls_first) {
+ unsigned int x;
+ for (x = 0; x < sdp->sd_journals; x++) {
+ error = gfs2_recover_journal(gfs2_jdesc_find(sdp, x),
+ WAIT);
+ if (error) {
+ fs_err(sdp, "error recovering journal %u: %d\n",
+ x, error);
+ goto fail_jinode_gh;
+ }
+ }
+
+ gfs2_lm_others_may_mount(sdp);
+ } else if (!sdp->sd_args.ar_spectator) {
+ error = gfs2_recover_journal(sdp->sd_jdesc, WAIT);
+ if (error) {
+ fs_err(sdp, "error recovering my journal: %d\n", error);
+ goto fail_jinode_gh;
+ }
+ }
+
+ set_bit(SDF_JOURNAL_CHECKED, &sdp->sd_flags);
+ gfs2_glock_dq_uninit(&ji_gh);
+ jindex = 0;
+
+ /* Disown my Journal glock */
+
+ sdp->sd_journal_gh.gh_owner = NULL;
+ sdp->sd_jinode_gh.gh_owner = NULL;
+
+ p = kthread_run(gfs2_recoverd, sdp, "gfs2_recoverd");
+ error = IS_ERR(p);
+ if (error) {
+ fs_err(sdp, "can't start recoverd thread: %d\n", error);
+ goto fail_jinode_gh;
+ }
+ sdp->sd_recoverd_process = p;
+
+ return 0;
+
+ fail_recoverd:
+ kthread_stop(sdp->sd_recoverd_process);
+
+ fail_jinode_gh:
+ if (!sdp->sd_args.ar_spectator)
+ gfs2_glock_dq_uninit(&sdp->sd_jinode_gh);
+
+ fail_journal_gh:
+ if (!sdp->sd_args.ar_spectator)
+ gfs2_glock_dq_uninit(&sdp->sd_journal_gh);
+
+ fail_jindex:
+ gfs2_jindex_free(sdp);
+ if (jindex)
+ gfs2_glock_dq_uninit(&ji_gh);
+
+ fail:
+ gfs2_inode_put(sdp->sd_jindex);
+
+ return error;
+}
|