diff options
author | Eric Sandeen <sandeen@redhat.com> | 2006-11-16 04:19:22 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-11-16 14:43:38 -0500 |
commit | d6ddf55440833fd9404138026af246c51ebeef22 (patch) | |
tree | 095984ba56a4f6eb14379f77bc6b0fbd49cf7f6a /fs | |
parent | 4c1b6d18bf2fdeb5ac725126c6928aaa98c8e22f (diff) |
[PATCH] hfs_fill_super returns success even if no root inode
http://kernelfun.blogspot.com/2006/11/mokb-14-11-2006-linux-26x-selinux.html
mount that image...
fs: filesystem was not cleanly unmounted, running fsck.hfs is recommended. mounting read-only.
hfs: get root inode failed.
BUG: unable to handle kernel NULL pointer dereference at virtual address 00000018
printing eip
...
EIP is at superblock_doinit+0x21/0x767
...
[] selinux_sb_kern_mount+0xc/0x4b
[] vfs_kern_mount+0x99/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
hfs_fill_super() returns success even if
root_inode = hfs_iget(sb, &fd.search_key->cat, &rec);
or
sb->s_root = d_alloc_root(root_inode);
fails. This superblock finds its way to superblock_doinit() which does:
struct dentry *root = sb->s_root;
struct inode *inode = root->d_inode;
and boom. Need to make sure the error cases return an error, I think.
[akpm@osdl.org: return -ENOMEM on oom]
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/hfs/super.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index d43b4fcc8ad3..85b17b3fa4a0 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
@@ -390,11 +390,13 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) | |||
390 | hfs_find_exit(&fd); | 390 | hfs_find_exit(&fd); |
391 | goto bail_no_root; | 391 | goto bail_no_root; |
392 | } | 392 | } |
393 | res = -EINVAL; | ||
393 | root_inode = hfs_iget(sb, &fd.search_key->cat, &rec); | 394 | root_inode = hfs_iget(sb, &fd.search_key->cat, &rec); |
394 | hfs_find_exit(&fd); | 395 | hfs_find_exit(&fd); |
395 | if (!root_inode) | 396 | if (!root_inode) |
396 | goto bail_no_root; | 397 | goto bail_no_root; |
397 | 398 | ||
399 | res = -ENOMEM; | ||
398 | sb->s_root = d_alloc_root(root_inode); | 400 | sb->s_root = d_alloc_root(root_inode); |
399 | if (!sb->s_root) | 401 | if (!sb->s_root) |
400 | goto bail_iput; | 402 | goto bail_iput; |