diff options
author | NeilBrown <neilb@suse.de> | 2006-09-16 15:15:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-16 15:54:31 -0400 |
commit | fdb36673a9d6accf93b11e7eff3a7e34cd284616 (patch) | |
tree | 3e34c42fc03b4606f834e0516a62417082fd1ab0 /fs/ext3/super.c | |
parent | ecaff756ff540f3821e2b00b8fa19aca07c7c3e5 (diff) |
[PATCH] knfsd: Make ext3 reject filehandles referring to invalid inode number
Inodes earlier than the 'first' inode (e.g. journal, resize) should be
rejected early - except the root inode. Also inode numbers that are too
big should be rejected early.
[akpm@osdl.org: cleanup]
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/ext3/super.c')
-rw-r--r-- | fs/ext3/super.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 813d589cc6c0..3559086eee5f 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -554,6 +554,47 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
554 | return 0; | 554 | return 0; |
555 | } | 555 | } |
556 | 556 | ||
557 | |||
558 | static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp) | ||
559 | { | ||
560 | __u32 *objp = vobjp; | ||
561 | unsigned long ino = objp[0]; | ||
562 | __u32 generation = objp[1]; | ||
563 | struct inode *inode; | ||
564 | struct dentry *result; | ||
565 | |||
566 | if (ino < EXT3_FIRST_INO(sb) && ino != EXT3_ROOT_INO) | ||
567 | return ERR_PTR(-ESTALE); | ||
568 | if (ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)) | ||
569 | return ERR_PTR(-ESTALE); | ||
570 | |||
571 | /* iget isn't really right if the inode is currently unallocated!! | ||
572 | * | ||
573 | * ext3_read_inode will return a bad_inode if the inode had been | ||
574 | * deleted, so we should be safe. | ||
575 | * | ||
576 | * Currently we don't know the generation for parent directory, so | ||
577 | * a generation of 0 means "accept any" | ||
578 | */ | ||
579 | inode = iget(sb, ino); | ||
580 | if (inode == NULL) | ||
581 | return ERR_PTR(-ENOMEM); | ||
582 | if (is_bad_inode(inode) || | ||
583 | (generation && inode->i_generation != generation)) { | ||
584 | iput(inode); | ||
585 | return ERR_PTR(-ESTALE); | ||
586 | } | ||
587 | /* now to find a dentry. | ||
588 | * If possible, get a well-connected one | ||
589 | */ | ||
590 | result = d_alloc_anon(inode); | ||
591 | if (!result) { | ||
592 | iput(inode); | ||
593 | return ERR_PTR(-ENOMEM); | ||
594 | } | ||
595 | return result; | ||
596 | } | ||
597 | |||
557 | #ifdef CONFIG_QUOTA | 598 | #ifdef CONFIG_QUOTA |
558 | #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") | 599 | #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") |
559 | #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) | 600 | #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) |
@@ -622,6 +663,7 @@ static struct super_operations ext3_sops = { | |||
622 | 663 | ||
623 | static struct export_operations ext3_export_ops = { | 664 | static struct export_operations ext3_export_ops = { |
624 | .get_parent = ext3_get_parent, | 665 | .get_parent = ext3_get_parent, |
666 | .get_dentry = ext3_get_dentry, | ||
625 | }; | 667 | }; |
626 | 668 | ||
627 | enum { | 669 | enum { |