Bug 7737 - ReiserFS Sync Memory Corruption (CVE-2006-6128)
Summary: ReiserFS Sync Memory Corruption (CVE-2006-6128)
Status: CLOSED PATCH_ALREADY_AVAILABLE
Alias: None
Product: File System
Classification: Unclassified
Component: ReiserFS (show other bugs)
Hardware: i386 Linux
: P2 normal
Assignee: Eric Sandeen
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-12-23 07:52 UTC by Daniel Drake
Modified: 2007-08-14 09:20 UTC (History)
1 user (show)

See Also:
Kernel Version: 2.6.19
Subsystem:
Regression: ---
Bisected commit-id:


Attachments

Description Daniel Drake 2006-12-23 07:52:35 UTC
This vuln still appears to be unpatched, although I apologise if I made an
oversight.

http://projects.info-pull.com/mokb/MOKB-25-11-2006.html

The ReiserFS support code of Linux 2.6.x fails to properly handle crafted data
structures, leading to an exploitable memory corruption condition when a sync is
being done in a corrupted ReiserFS filesystem.

See the URL for a filesystem image where this bug can be reproduced.

BUG: unable to handle kernel paging request at virtual address 00010179
 printing eip:
c048cee3
*pde = 00000000
Oops: 0002 [#1]
SMP
last sysfs file: /block/loop7/range
Modules linked in: reiserfs jfs 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 gameport snd_rawmidi snd_ac97_codec snd_ac97_bus snd_seq_dummy
snd_seq_oss snd_seq_midi_event snd_seq
floppy snd_seq_device sg snd_pcm_oss snd_mixer_oss snd_pcm i2c_piix4 pcspkr
snd_timer snd soundcore pcnet32
snd_page_alloc i2c_core mii serio_raw ide_cd cdrom dm_snapshot dm_zero dm_mirror
dm_mod mptspi mptscsih mptbase
scsi_transport_spi sd_mod scsi_mod ext3 jbd ehci_hcd ohci_hcd uhci_hcd

CPU:    1
EIP:    0060:[<c048cee3>]    Not tainted VLI
EFLAGS: 00010203   (2.6.18-1.2849.fc6 #1)
EIP is at set_sb_syncing+0x14/0x2c
eax: 00010101   ebx: 00000000   ecx: c067b720   edx: 00000001
esi: 0804a785   edi: bfb73ec4   ebp: cfbb3000   esp: cfbb3f9c
ds: 007b   es: 007b   ss: 0068
Process sync (pid: 5171, ti=cfbb3000 task=cc6eb5f0 task.ti=cfbb3000)
Stack: 00000000 c048d6f0 00000001 c04718c2 0804a785 0804c4d4 c0471913 c0404013
       0804c4d4 00000000 00000001 0804a785 bfb73ec4 bfb73e28 00000024 0000007b
       0000007b 00000024 00c9a402 00000073 00000246 bfb73de8 0000007b 00000000
Call Trace:
 [<c048d6f0>] sync_inodes+0xa/0x29
 [<c04718c2>] do_sync+0x14/0x5b
 [<c0471913>] sys_sync+0xa/0xd
 [<c0404013>] syscall_call+0x7/0xb
DWARF2 unwinder stuck at syscall_call+0x7/0xb
Leftover inexact backtrace:
 =======================
Code: ff ff ff 85 c0 75 08 0f 0b b4 02 ff a1 63 c0 f0 0f ba 73 04 00 5b c3 53 89
c3 b8 78 64 68 c0 e8 1f 76
      18 00 a1 74 64 68 c0 eb 06 <89> 58 78 8b 40 04 3d 70 64 68 c0 75 f3 5b b8
78 64 68 c0 e9 d3
EIP: [<c048cee3>] set_sb_syncing+0x14/0x2c SS:ESP 0068:cfbb3f9c
 <3>BUG: soft lockup detected on CPU#0!
 [<c04051db>] dump_trace+0x69/0x1af
 [<c0405339>] show_trace_log_lvl+0x18/0x2c
 [<c04058ed>] show_trace+0xf/0x11
 [<c04059ea>] dump_stack+0x15/0x17
 [<c044da8d>] softlockup_tick+0xad/0xc4
 [<c042e59a>] update_process_times+0x39/0x5c
 [<c0418914>] smp_apic_timer_interrupt+0x5c/0x64
 [<c0404ad3>] apic_timer_interrupt+0x1f/0x24
DWARF2 unwinder stuck at apic_timer_interrupt+0x1f/0x24
Leftover inexact backtrace:
 [<c04e9807>] _raw_spin_lock+0x6f/0xdc
 [<c0612ccc>] schedule+0x960/0x9dd
 [<c04db682>] blk_congestion_wait+0x5e/0x67
 [<c048d732>] writeback_inodes+0x23/0xc3
 [<c0458a22>] background_writeout+0x6f/0x9a
 [<c0458f32>] pdflush+0x0/0x1aa
 [<c0459043>] pdflush+0x111/0x1aa
 [<c04589b3>] background_writeout+0x0/0x9a
 [<c04369fb>] kthread+0xc0/0xed
 [<c043693b>] kthread+0x0/0xed
 [<c0404dab>] kernel_thread_helper+0x7/0x10
 =======================
BUG: soft lockup detected on CPU#1!
 [<c04051db>] dump_trace+0x69/0x1af
 [<c0405339>] show_trace_log_lvl+0x18/0x2c
 [<c04058ed>] show_trace+0xf/0x11
 [<c04059ea>] dump_stack+0x15/0x17
 [<c044da8d>] softlockup_tick+0xad/0xc4
 [<c042e59a>] update_process_times+0x39/0x5c
 [<c0418914>] smp_apic_timer_interrupt+0x5c/0x64
 [<c0404ad3>] apic_timer_interrupt+0x1f/0x24
 =======================
Comment 1 Diego Calleja 2006-12-23 16:16:03 UTC
Please next time contact security@kernel.org first
Comment 2 Eric Sandeen 2007-08-14 09:19:36 UTC
This one seems to be unique to a patch in the fedora kernel; see also 
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=250625

It was fixed as of kernel-2.6.19-1.2911.fc6

-----

linux-2.6-reiserfs-dentry-ref.patch did:

-       .kill_sb = kill_block_super,
+       .kill_sb = reiserfs_kill_sb,


and then:

+static void reiserfs_kill_sb(struct super_block *s)
+{
+       if (REISERFS_SB(s)) {
+               if (REISERFS_SB(s)->xattr_root) {
+                       d_invalidate(REISERFS_SB(s)->xattr_root);
+                       dput(REISERFS_SB(s)->xattr_root);
+                       REISERFS_SB(s)->xattr_root = NULL;
+               }
+               if (REISERFS_SB(s)->priv_root) {
+                       d_invalidate(REISERFS_SB(s)->priv_root);
+                       dput(REISERFS_SB(s)->priv_root);
+                       REISERFS_SB(s)->priv_root = NULL;
+               }
+               kill_block_super(s);
+       }
+}

but that means the VFS superblock never goes through kill_block_super if the
reiser-specific SB isn't there.  Upstream is:

static void reiserfs_kill_sb(struct super_block *s)
{
        if (REISERFS_SB(s)) {
#ifdef CONFIG_REISERFS_FS_XATTR
                if (REISERFS_SB(s)->xattr_root) {
                        d_invalidate(REISERFS_SB(s)->xattr_root);
                        dput(REISERFS_SB(s)->xattr_root);
                        REISERFS_SB(s)->xattr_root = NULL;
                }
#endif
                if (REISERFS_SB(s)->priv_root) {
                        d_invalidate(REISERFS_SB(s)->priv_root);
                        dput(REISERFS_SB(s)->priv_root);
                        REISERFS_SB(s)->priv_root = NULL;
                }
        }

        kill_block_super(s);
}

i.e. call kill_block_super in all cases.

(see also
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=edc666e2ff9ec2e4e9510f1127c68c22cffc93f6)

w/o  that kill_block_super the half-set-up superblock is hanging around on a
failed mount, waiting to go boom.

-Eric

Note You need to log in before you can comment on or make changes to this bug.