Commit b2a51555 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Fix memory leak in hugetlbfs

From: "Chen, Kenneth W" <kenneth.w.chen@intel.com>

The hugetlbfs_fill_super() doesn't free up memory allocated for sbinfo on
the way out in case of parsing error (and a few others).  This leads to
memory leak If root tries to mount a hugetlbfs with invalid mount option.
Here is a patch that fix the problem.
parent 3c28ea40
...@@ -648,11 +648,6 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -648,11 +648,6 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
struct hugetlbfs_config config; struct hugetlbfs_config config;
struct hugetlbfs_sb_info *sbinfo; struct hugetlbfs_sb_info *sbinfo;
sbinfo = kmalloc(sizeof(struct hugetlbfs_sb_info), GFP_KERNEL);
if (!sbinfo)
return -ENOMEM;
sb->s_fs_info = sbinfo;
config.nr_blocks = -1; /* No limit on size by default */ config.nr_blocks = -1; /* No limit on size by default */
config.nr_inodes = -1; /* No limit on number of inodes by default */ config.nr_inodes = -1; /* No limit on number of inodes by default */
config.uid = current->fsuid; config.uid = current->fsuid;
...@@ -663,6 +658,10 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -663,6 +658,10 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
if (ret) if (ret)
return ret; return ret;
sbinfo = kmalloc(sizeof(struct hugetlbfs_sb_info), GFP_KERNEL);
if (!sbinfo)
return -ENOMEM;
sb->s_fs_info = sbinfo;
spin_lock_init(&sbinfo->stat_lock); spin_lock_init(&sbinfo->stat_lock);
sbinfo->max_blocks = config.nr_blocks; sbinfo->max_blocks = config.nr_blocks;
sbinfo->free_blocks = config.nr_blocks; sbinfo->free_blocks = config.nr_blocks;
...@@ -675,15 +674,18 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -675,15 +674,18 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
inode = hugetlbfs_get_inode(sb, config.uid, config.gid, inode = hugetlbfs_get_inode(sb, config.uid, config.gid,
S_IFDIR | config.mode, 0); S_IFDIR | config.mode, 0);
if (!inode) if (!inode)
return -ENOMEM; goto out_free;
root = d_alloc_root(inode); root = d_alloc_root(inode);
if (!root) { if (!root) {
iput(inode); iput(inode);
return -ENOMEM; goto out_free;
} }
sb->s_root = root; sb->s_root = root;
return 0; return 0;
out_free:
kfree(sbinfo);
return -ENOMEM;
} }
int hugetlb_get_quota(struct address_space *mapping) int hugetlb_get_quota(struct address_space *mapping)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment