From bb70d76497c068c10d9bbb04f3ad534e59f93321 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 12 Jul 2014 22:16:39 +0400 Subject: [PATCH] Add BUG_ON() after each sb_bread() to avoid NULL dereferencing If mkfs-simple will have bugs, than it could obtain illegal block number, and sb_bread() will return NULL, even without it could return NULL, so since this fs is just for testing, simply add bug_on() to avoid going further. [ 1247.861163] The magic number obtained in disk is: [268640275] [ 1247.861165] simplefs filesystem of version [1] formatted with a block size of [4096] detected in the device. [ 1247.861194] simplefs is succesfully mounted on [/dev/loop0] [ 1247.886800] BUG: unable to handle kernel NULL pointer dereference at (null) [ 1247.886804] IP: [] simplefs_lookup+0xb5/0x180 [simplefs] [ 1247.886808] PGD 5eda6067 PUD 5eda5067 PMD 0 [ 1247.886810] Oops: 0000 [#1] SMP [ 1247.886812] Modules linked in: simplefs(POE) snd_intel8x0 snd_ac97_codec ac97_bus snd_pcm snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device intel_rapl snd_timer joydev snd rfcomm bnep bluetooth 6lowpan_iphc serio_raw i2c_piix4 mac_hid soundcore parport_pc ppdev lp parport hid_generic usbhid hid psmouse ahci libahci e1000 pata_acpi [last unloaded: simplefs] [ 1247.886826] CPU: 0 PID: 9467 Comm: cat Tainted: P OE 3.15.0-6-generic #11-Ubuntu [ 1247.886827] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 1247.886828] task: ffff88005e72cb90 ti: ffff88005ede8000 task.ti: ffff88005ede8000 [ 1247.886829] RIP: 0010:[] [] simplefs_lookup+0xb5/0x180 [simplefs] [ 1247.886832] RSP: 0018:ffff88005edebc88 EFLAGS: 00010292 [ 1247.886833] RAX: 0000000000000002 RBX: 0000000000000000 RCX: ffff88005f5370a0 [ 1247.886834] RDX: ffff880024c9a108 RSI: ffff880024c9bb60 RDI: ffff880024c9a000 [ 1247.886834] RBP: ffff88005edebcc0 R08: 0000000000000000 R09: 0000000000000001 [ 1247.886835] R10: ffff88005edebab8 R11: 0000000000000000 R12: ffff88005f537000 [ 1247.886836] R13: ffff88005ed68000 R14: 0000000000000000 R15: ffff880024c9a000 [ 1247.886837] FS: 00007ffb35497740(0000) GS:ffff880065c00000(0000) knlGS:0000000000000000 [ 1247.886838] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1247.886839] CR2: 0000000000000000 CR3: 000000005edfa000 CR4: 00000000000006f0 [ 1247.886843] Stack: [ 1247.886844] ffff880024c9bb60 ffff88001d19e180 ffff88001d19e180 0000000000008000 [ 1247.886845] ffff88005edebde8 ffff88001d159e40 ffff88005edebe40 ffff88005edebce0 [ 1247.886847] ffffffff811da5ed ffff88001d159e40 ffff88005edebf2c ffff88005edebd88 [ 1247.886848] Call Trace: [ 1247.886853] [] lookup_real+0x1d/0x70 [ 1247.886856] [] do_last+0x797/0x1270 [ 1247.886860] [] ? apparmor_file_alloc_security+0x5b/0x180 [ 1247.886862] [] ? security_file_alloc+0x16/0x20 [ 1247.886864] [] path_openat+0xbb/0x6a0 [ 1247.886866] [] do_filp_open+0x3a/0xa0 [ 1247.886868] [] ? __alloc_fd+0xa7/0x130 [ 1247.886871] [] do_sys_open+0x12a/0x280 [ 1247.886874] [] ? syscall_trace_enter+0x165/0x2a0 [ 1247.886876] [] SyS_open+0x1e/0x20 [ 1247.886879] [] tracesys+0xe1/0xe6 [ 1247.886880] Code: 01 00 00 4c 89 e7 e8 ab fe ff ff 4c 89 e7 48 89 c3 e8 f0 38 12 e1 49 89 c7 49 8b 85 00 01 00 00 48 8b 34 24 4c 89 ff 49 89 47 40 <0f> b7 13 e8 83 0f 12 e1 41 0f b7 07 4d 89 67 28 49 c7 47 20 40 [ 1247.886894] RIP [] simplefs_lookup+0xb5/0x180 [simplefs] [ 1247.886896] RSP [ 1247.886896] CR2: 0000000000000000 [ 1247.886898] ---[ end trace 89702ff0fda32679 ]--- --- simple.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/simple.c b/simple.c index 6feac2f..53c384a 100644 --- a/simple.c +++ b/simple.c @@ -39,6 +39,8 @@ void simplefs_sb_sync(struct super_block *vsb) struct simplefs_super_block *sb = SIMPLEFS_SB(vsb); bh = sb_bread(vsb, SIMPLEFS_SUPERBLOCK_BLOCK_NUMBER); + BUG_ON(!bh); + bh->b_data = (char *)sb; mark_buffer_dirty(bh); sync_dirty_buffer(bh); @@ -75,6 +77,7 @@ void simplefs_inode_add(struct super_block *vsb, struct simplefs_inode *inode) } bh = sb_bread(vsb, SIMPLEFS_INODESTORE_BLOCK_NUMBER); + BUG_ON(!bh); inode_iterator = (struct simplefs_inode *)bh->b_data; @@ -198,6 +201,7 @@ static int simplefs_readdir(struct file *filp, void *dirent, filldir_t filldir) } bh = sb_bread(sb, sfs_inode->data_block_number); + BUG_ON(!bh); record = (struct simplefs_dir_record *)bh->b_data; for (i = 0; i < sfs_inode->dir_children_count; i++) { @@ -234,6 +238,8 @@ struct simplefs_inode *simplefs_get_inode(struct super_block *sb, * But such a model will not be scalable in a filesystem with * millions or billions of files (inodes) */ bh = sb_bread(sb, SIMPLEFS_INODESTORE_BLOCK_NUMBER); + BUG_ON(!bh); + sfs_inode = (struct simplefs_inode *)bh->b_data; #if 0 @@ -309,6 +315,7 @@ int simplefs_inode_save(struct super_block *sb, struct simplefs_inode *sfs_inode struct buffer_head *bh; bh = sb_bread(sb, SIMPLEFS_INODESTORE_BLOCK_NUMBER); + BUG_ON(!bh); if (mutex_lock_interruptible(&simplefs_sb_lock)) { sfs_trace("Failed to acquire mutex lock\n"); @@ -522,6 +529,8 @@ static int simplefs_create_fs_object(struct inode *dir, struct dentry *dentry, parent_dir_inode = SIMPLEFS_INODE(dir); bh = sb_bread(sb, parent_dir_inode->data_block_number); + BUG_ON(!bh); + dir_contents_datablock = (struct simplefs_dir_record *)bh->b_data; /* Navigate to the last record in the directory contents */ @@ -585,6 +594,8 @@ struct dentry *simplefs_lookup(struct inode *parent_inode, int i; bh = sb_bread(sb, parent->data_block_number); + BUG_ON(!bh); + record = (struct simplefs_dir_record *)bh->b_data; for (i = 0; i < parent->dir_children_count; i++) { if (!strcmp(record->filename, child_dentry->d_name.name)) { @@ -659,6 +670,7 @@ int simplefs_fill_super(struct super_block *sb, void *data, int silent) int ret = -EPERM; bh = sb_bread(sb, SIMPLEFS_SUPERBLOCK_BLOCK_NUMBER); + BUG_ON(!bh); sb_disk = (struct simplefs_super_block *)bh->b_data;