| From stable-bounces@linux.kernel.org Fri Aug 4 08:36:24 2006 |
| Message-ID: <44D36946.7020601@redhat.com> |
| Date: Fri, 04 Aug 2006 10:35:34 -0500 |
| From: Eric Sandeen <esandeen@redhat.com> |
| To: Christoph Hellwig <hch@infradead.org>, Eric Sandeen <esandeen@redhat.com>, |
| Greg KH <gregkh@suse.de>, linux-kernel@vger.kernel.org, |
| stable@kernel.org, torvalds@osdl.org, |
| Justin Forbes <jmforbes@linuxtx.org>, |
| Zwane Mwaikambo <zwane@arm.linux.org.uk>, |
| "Theodore Ts'o" <tytso@mit.edu>, Randy Dunlap <rdunlap@xenotime.net>, |
| Dave Jones <davej@redhat.com>, Chuck Wolber <chuckw@quantumlinux.com>, |
| Chris Wedgwood <reviews@ml.cw.f00f.org>, akpm@osdl.org, |
| alan@lxorguk.ukuu.org.uk, jack@suse.cz, neilb@suse.de, |
| Marcel Holtmann <marcel@holtmann.org>, |
| "Stephen C. Tweedie" <sct@redhat.com> |
| Subject: Have ext3 reject file handles with bad inode numbers early |
| |
| blatantly ripped off from Neil Brown's ext2 patch. |
| |
| |
| Signed-off-by: Eric Sandeen <sandeen@sandeen.net> |
| Acked-by: "Theodore Ts'o" <tytso@mit.edu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| fs/ext3/super.c | 40 ++++++++++++++++++++++++++++++++++++++++ |
| 1 file changed, 40 insertions(+) |
| |
| --- linux-2.6.17.8.orig/fs/ext3/super.c |
| +++ linux-2.6.17.8/fs/ext3/super.c |
| @@ -620,8 +620,48 @@ static struct super_operations ext3_sops |
| #endif |
| }; |
| |
| +static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp) |
| +{ |
| + __u32 *objp = vobjp; |
| + unsigned long ino = objp[0]; |
| + __u32 generation = objp[1]; |
| + struct inode *inode; |
| + struct dentry *result; |
| + |
| + if (ino != EXT3_ROOT_INO && ino < EXT3_FIRST_INO(sb)) |
| + return ERR_PTR(-ESTALE); |
| + if (ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)) |
| + return ERR_PTR(-ESTALE); |
| + |
| + /* iget isn't really right if the inode is currently unallocated!! |
| + * ext3_read_inode currently does appropriate checks, but |
| + * it might be "neater" to call ext3_get_inode first and check |
| + * if the inode is valid..... |
| + */ |
| + inode = iget(sb, ino); |
| + if (inode == NULL) |
| + return ERR_PTR(-ENOMEM); |
| + if (is_bad_inode(inode) |
| + || (generation && inode->i_generation != generation) |
| + ) { |
| + /* we didn't find the right inode.. */ |
| + iput(inode); |
| + return ERR_PTR(-ESTALE); |
| + } |
| + /* now to find a dentry. |
| + * If possible, get a well-connected one |
| + */ |
| + result = d_alloc_anon(inode); |
| + if (!result) { |
| + iput(inode); |
| + return ERR_PTR(-ENOMEM); |
| + } |
| + return result; |
| +} |
| + |
| static struct export_operations ext3_export_ops = { |
| .get_parent = ext3_get_parent, |
| + .get_dentry = ext3_get_dentry, |
| }; |
| |
| enum { |