fat: fix memory allocation failure handling of match_strdup()
Subsystems (2)
PATCH 4/6 fat: fix memory allocation failure handling of match_strdup()
From: OGAWA Hirofumi <[email protected]>
Subject: fat: fix memory allocation failure handling of match_strdup()
In parse_options(), if match_strdup() failed, parse_options() leaves opts->iocharset in unexpected state (i.e. still pointing the freed string). And this can be the cause of double free.
To fix, this initialize opts->iocharset always when freeing.
Signed-off-by OGAWA Hirofumi <[email protected]>
Reported-by [email protected]
Cc <[email protected]>
Signed-off-by Andrew Morton <[email protected]>
---
fs/fat/inode.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
fs/fat/inode.c renamed from fs/fat/inode.c~fat-fix-memory-allocation-failure-handling-of-match_strdup +13 -7
@@ -707,13 +707,21 @@ static void fat_set_state(struct super_bbrelse (bh); } +static void fat_reset_iocharset (struct fat_mount_options *opts) +{ +if (opts->iocharset != fat_default_iocharset) { +/* Note: opts->iocharset can be NULL here */ +kfree (opts->iocharset); + opts->iocharset = fat_default_iocharset; + } +} +static void delayed_free (struct rcu_head *p) { struct msdos_sb_info *sbi = container_of(p, struct msdos_sb_info, rcu);unload_nls (sbi->nls_disk);unload_nls (sbi->nls_io); -if (sbi->options.iocharset != fat_default_iocharset) -kfree (sbi->options.iocharset); +fat_reset_iocharset (&sbi->options);kfree (sbi); }
@@ -1132,7 +1140,7 @@ static int parse_options(struct super_bl opts->fs_fmask = opts->fs_dmask =current_umask (); opts->allow_utime =-1 ; opts->codepage = fat_default_codepage; - opts->iocharset = fat_default_iocharset; +fat_reset_iocharset (opts);if (is_vfat) { opts->shortname =VFAT_SFN_DISPLAY_WINNT |VFAT_SFN_CREATE_WIN95 ; opts->rodir =0 ;
@@ -1289,8 +1297,7 @@ static int parse_options(struct super_bl/* vfat specific */ case Opt_charset: -if (opts->iocharset != fat_default_iocharset) -kfree (opts->iocharset); +fat_reset_iocharset (opts); iocharset =match_strdup (&args[0 ]);if (!iocharset)return -ENOMEM ;
@@ -1881,8 +1888,7 @@ out_fail:iput (fat_inode);unload_nls (sbi->nls_io);unload_nls (sbi->nls_disk); -if (sbi->options.iocharset != fat_default_iocharset) -kfree (sbi->options.iocharset); +fat_reset_iocharset (&sbi->options); sb->s_fs_info =NULL ;kfree (sbi);return error;
_