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: [<ffffffffa00ca695>] 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:[<ffffffffa00ca695>]  [<ffffffffa00ca695>] 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]  [<ffffffff811da5ed>] lookup_real+0x1d/0x70
[ 1247.886856]  [<ffffffff811df537>] do_last+0x797/0x1270
[ 1247.886860]  [<ffffffff8132c81b>] ? apparmor_file_alloc_security+0x5b/0x180
[ 1247.886862]  [<ffffffff812ed116>] ? security_file_alloc+0x16/0x20
[ 1247.886864]  [<ffffffff811e119b>] path_openat+0xbb/0x6a0
[ 1247.886866]  [<ffffffff811e285a>] do_filp_open+0x3a/0xa0
[ 1247.886868]  [<ffffffff811ef597>] ? __alloc_fd+0xa7/0x130
[ 1247.886871]  [<ffffffff811cff8a>] do_sys_open+0x12a/0x280
[ 1247.886874]  [<ffffffff81020925>] ? syscall_trace_enter+0x165/0x2a0
[ 1247.886876]  [<ffffffff811d00fe>] SyS_open+0x1e/0x20
[ 1247.886879]  [<ffffffff8176e33f>] 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  [<ffffffffa00ca695>] simplefs_lookup+0xb5/0x180 [simplefs]
[ 1247.886896]  RSP <ffff88005edebc88>
[ 1247.886896] CR2: 0000000000000000
[ 1247.886898] ---[ end trace 89702ff0fda32679 ]---
This commit is contained in:
Azat Khuzhin 2014-07-12 22:16:39 +04:00
parent 069f34ebbc
commit bb70d76497

View File

@ -39,6 +39,8 @@ void simplefs_sb_sync(struct super_block *vsb)
struct simplefs_super_block *sb = SIMPLEFS_SB(vsb); struct simplefs_super_block *sb = SIMPLEFS_SB(vsb);
bh = sb_bread(vsb, SIMPLEFS_SUPERBLOCK_BLOCK_NUMBER); bh = sb_bread(vsb, SIMPLEFS_SUPERBLOCK_BLOCK_NUMBER);
BUG_ON(!bh);
bh->b_data = (char *)sb; bh->b_data = (char *)sb;
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
sync_dirty_buffer(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); bh = sb_bread(vsb, SIMPLEFS_INODESTORE_BLOCK_NUMBER);
BUG_ON(!bh);
inode_iterator = (struct simplefs_inode *)bh->b_data; 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); bh = sb_bread(sb, sfs_inode->data_block_number);
BUG_ON(!bh);
record = (struct simplefs_dir_record *)bh->b_data; record = (struct simplefs_dir_record *)bh->b_data;
for (i = 0; i < sfs_inode->dir_children_count; i++) { 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 * But such a model will not be scalable in a filesystem with
* millions or billions of files (inodes) */ * millions or billions of files (inodes) */
bh = sb_bread(sb, SIMPLEFS_INODESTORE_BLOCK_NUMBER); bh = sb_bread(sb, SIMPLEFS_INODESTORE_BLOCK_NUMBER);
BUG_ON(!bh);
sfs_inode = (struct simplefs_inode *)bh->b_data; sfs_inode = (struct simplefs_inode *)bh->b_data;
#if 0 #if 0
@ -309,6 +315,7 @@ int simplefs_inode_save(struct super_block *sb, struct simplefs_inode *sfs_inode
struct buffer_head *bh; struct buffer_head *bh;
bh = sb_bread(sb, SIMPLEFS_INODESTORE_BLOCK_NUMBER); bh = sb_bread(sb, SIMPLEFS_INODESTORE_BLOCK_NUMBER);
BUG_ON(!bh);
if (mutex_lock_interruptible(&simplefs_sb_lock)) { if (mutex_lock_interruptible(&simplefs_sb_lock)) {
sfs_trace("Failed to acquire mutex lock\n"); 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); parent_dir_inode = SIMPLEFS_INODE(dir);
bh = sb_bread(sb, parent_dir_inode->data_block_number); bh = sb_bread(sb, parent_dir_inode->data_block_number);
BUG_ON(!bh);
dir_contents_datablock = (struct simplefs_dir_record *)bh->b_data; dir_contents_datablock = (struct simplefs_dir_record *)bh->b_data;
/* Navigate to the last record in the directory contents */ /* Navigate to the last record in the directory contents */
@ -585,6 +594,8 @@ struct dentry *simplefs_lookup(struct inode *parent_inode,
int i; int i;
bh = sb_bread(sb, parent->data_block_number); bh = sb_bread(sb, parent->data_block_number);
BUG_ON(!bh);
record = (struct simplefs_dir_record *)bh->b_data; record = (struct simplefs_dir_record *)bh->b_data;
for (i = 0; i < parent->dir_children_count; i++) { for (i = 0; i < parent->dir_children_count; i++) {
if (!strcmp(record->filename, child_dentry->d_name.name)) { 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; int ret = -EPERM;
bh = sb_bread(sb, SIMPLEFS_SUPERBLOCK_BLOCK_NUMBER); bh = sb_bread(sb, SIMPLEFS_SUPERBLOCK_BLOCK_NUMBER);
BUG_ON(!bh);
sb_disk = (struct simplefs_super_block *)bh->b_data; sb_disk = (struct simplefs_super_block *)bh->b_data;