
From: Zwane Mwaikambo <zwane@linuxpower.ca>

hugetlbfs was accessing super_block->s_fs_info after free'ing it.  This was
because it was being free'd prematurely.  I have deferred free until
->put_super().  I have also removed hugetlbfs_kill_super since it now is
simply a kill_litter_super.



 fs/hugetlbfs/inode.c |   22 ++++++++++++----------
 1 files changed, 12 insertions(+), 10 deletions(-)

diff -puN fs/hugetlbfs/inode.c~hugetlbfs-use-after-free-fix fs/hugetlbfs/inode.c
--- 25/fs/hugetlbfs/inode.c~hugetlbfs-use-after-free-fix	2003-08-10 17:00:15.000000000 -0700
+++ 25-akpm/fs/hugetlbfs/inode.c	2003-08-10 17:00:15.000000000 -0700
@@ -575,6 +575,16 @@ static int hugetlbfs_rename(struct inode
 	return 0;
 }
 
+static void hugetlbfs_put_super(struct super_block *sb)
+{
+	struct hugetlbfs_sb_info *sbi = HUGETLBFS_SB(sb);
+
+	if (sbi) {
+		sb->s_fs_info = NULL;
+		kfree(sbi);
+	}
+}
+
 static struct address_space_operations hugetlbfs_aops = {
 	.readpage	= hugetlbfs_readpage,
 	.prepare_write	= hugetlbfs_prepare_write,
@@ -608,6 +618,7 @@ static struct inode_operations hugetlbfs
 static struct super_operations hugetlbfs_ops = {
 	.statfs		= hugetlbfs_statfs,
 	.drop_inode	= hugetlbfs_drop_inode,
+	.put_super	= hugetlbfs_put_super,
 };
 
 static int
@@ -709,19 +720,10 @@ static struct super_block *hugetlbfs_get
 	return get_sb_nodev(fs_type, flags, data, hugetlbfs_fill_super);
 }
 
-static void hugetlbfs_kill_super(struct super_block *sb)
-{
-	if (sb) {
-		if(sb->s_fs_info)
-			kfree(sb->s_fs_info);
-		kill_litter_super(sb);
-	}
-}
-
 static struct file_system_type hugetlbfs_fs_type = {
 	.name		= "hugetlbfs",
 	.get_sb		= hugetlbfs_get_sb,
-	.kill_sb	= hugetlbfs_kill_super
+	.kill_sb	= kill_litter_super,
 };
 
 static struct vfsmount *hugetlbfs_vfsmount;

_
