aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@gmail.com>2010-07-27 11:56:07 -0400
committerTheodore Ts'o <tytso@mit.edu>2010-07-27 11:56:07 -0400
commitdcc7dae3cb21184a317f10a12250bd8d6f458077 (patch)
tree1f40c22059a9ccbb0ef3ea6fde0e015290db2765
parent0c095c7f113e9fd05913d6e1b2cccbe356be039e (diff)
ext4: Fix potential memory leak in ext4_fill_super
Under heavy memory pressure we may hit out of memory situation and as result kstrdup'ed options will not be freed. Fix it. Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/ext4/super.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index ed00c14d7081..d573f6c1a4de 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2550,7 +2550,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2550 struct inode *root; 2550 struct inode *root;
2551 char *cp; 2551 char *cp;
2552 const char *descr; 2552 const char *descr;
2553 int ret = -EINVAL; 2553 int ret = -ENOMEM;
2554 int blocksize; 2554 int blocksize;
2555 unsigned int db_count; 2555 unsigned int db_count;
2556 unsigned int i; 2556 unsigned int i;
@@ -2561,13 +2561,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2561 2561
2562 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); 2562 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
2563 if (!sbi) 2563 if (!sbi)
2564 return -ENOMEM; 2564 goto out_free_orig;
2565 2565
2566 sbi->s_blockgroup_lock = 2566 sbi->s_blockgroup_lock =
2567 kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); 2567 kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL);
2568 if (!sbi->s_blockgroup_lock) { 2568 if (!sbi->s_blockgroup_lock) {
2569 kfree(sbi); 2569 kfree(sbi);
2570 return -ENOMEM; 2570 goto out_free_orig;
2571 } 2571 }
2572 sb->s_fs_info = sbi; 2572 sb->s_fs_info = sbi;
2573 sbi->s_mount_opt = 0; 2573 sbi->s_mount_opt = 0;
@@ -2584,6 +2584,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2584 for (cp = sb->s_id; (cp = strchr(cp, '/'));) 2584 for (cp = sb->s_id; (cp = strchr(cp, '/'));)
2585 *cp = '!'; 2585 *cp = '!';
2586 2586
2587 ret = -EINVAL;
2587 blocksize = sb_min_blocksize(sb, EXT4_MIN_BLOCK_SIZE); 2588 blocksize = sb_min_blocksize(sb, EXT4_MIN_BLOCK_SIZE);
2588 if (!blocksize) { 2589 if (!blocksize) {
2589 ext4_msg(sb, KERN_ERR, "unable to set blocksize"); 2590 ext4_msg(sb, KERN_ERR, "unable to set blocksize");
@@ -3190,6 +3191,7 @@ out_fail:
3190 kfree(sbi->s_blockgroup_lock); 3191 kfree(sbi->s_blockgroup_lock);
3191 kfree(sbi); 3192 kfree(sbi);
3192 lock_kernel(); 3193 lock_kernel();
3194out_free_orig:
3193 kfree(orig_data); 3195 kfree(orig_data);
3194 return ret; 3196 return ret;
3195} 3197}