diff options
author | Cyrill Gorcunov <gorcunov@gmail.com> | 2010-07-27 11:56:07 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2010-07-27 11:56:07 -0400 |
commit | dcc7dae3cb21184a317f10a12250bd8d6f458077 (patch) | |
tree | 1f40c22059a9ccbb0ef3ea6fde0e015290db2765 /fs/ext4/super.c | |
parent | 0c095c7f113e9fd05913d6e1b2cccbe356be039e (diff) | |
download | blackbird-op-linux-dcc7dae3cb21184a317f10a12250bd8d6f458077.tar.gz blackbird-op-linux-dcc7dae3cb21184a317f10a12250bd8d6f458077.zip |
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>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 8 |
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) struct inode *root; char *cp; const char *descr; - int ret = -EINVAL; + int ret = -ENOMEM; int blocksize; unsigned int db_count; unsigned int i; @@ -2561,13 +2561,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); if (!sbi) - return -ENOMEM; + goto out_free_orig; sbi->s_blockgroup_lock = kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); if (!sbi->s_blockgroup_lock) { kfree(sbi); - return -ENOMEM; + goto out_free_orig; } sb->s_fs_info = sbi; sbi->s_mount_opt = 0; @@ -2584,6 +2584,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) for (cp = sb->s_id; (cp = strchr(cp, '/'));) *cp = '!'; + ret = -EINVAL; blocksize = sb_min_blocksize(sb, EXT4_MIN_BLOCK_SIZE); if (!blocksize) { ext4_msg(sb, KERN_ERR, "unable to set blocksize"); @@ -3190,6 +3191,7 @@ out_fail: kfree(sbi->s_blockgroup_lock); kfree(sbi); lock_kernel(); +out_free_orig: kfree(orig_data); return ret; } |