提交 785dffe1 编写于 作者: C Chengguang Xu 提交者: Jan Kara

udf: fix potential refcnt problem of nls module

When specifiying iocharset multiple times in a mount or once/multiple in
a remount, current option parsing may cause inaccurate refcount of nls
module.  Also, in the failure cleanup of option parsing, the condition
of calling unload_nls is not sufficient.
Signed-off-by: NChengguang Xu <cgxu519@icloud.com>
Signed-off-by: NJan Kara <jack@suse.cz>
上级 d0909905
...@@ -477,7 +477,6 @@ static int udf_parse_options(char *options, struct udf_options *uopt, ...@@ -477,7 +477,6 @@ static int udf_parse_options(char *options, struct udf_options *uopt,
uopt->session = 0xFFFFFFFF; uopt->session = 0xFFFFFFFF;
uopt->lastblock = 0; uopt->lastblock = 0;
uopt->anchor = 0; uopt->anchor = 0;
uopt->nls_map = NULL;
if (!options) if (!options)
return 1; return 1;
...@@ -575,8 +574,12 @@ static int udf_parse_options(char *options, struct udf_options *uopt, ...@@ -575,8 +574,12 @@ static int udf_parse_options(char *options, struct udf_options *uopt,
break; break;
#ifdef CONFIG_UDF_NLS #ifdef CONFIG_UDF_NLS
case Opt_iocharset: case Opt_iocharset:
if (!remount) {
if (uopt->nls_map)
unload_nls(uopt->nls_map);
uopt->nls_map = load_nls(args[0].from); uopt->nls_map = load_nls(args[0].from);
uopt->flags |= (1 << UDF_FLAG_NLS_MAP); uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
}
break; break;
#endif #endif
case Opt_uforget: case Opt_uforget:
...@@ -627,6 +630,7 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) ...@@ -627,6 +630,7 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
uopt.umask = sbi->s_umask; uopt.umask = sbi->s_umask;
uopt.fmode = sbi->s_fmode; uopt.fmode = sbi->s_fmode;
uopt.dmode = sbi->s_dmode; uopt.dmode = sbi->s_dmode;
uopt.nls_map = NULL;
if (!udf_parse_options(options, &uopt, true)) if (!udf_parse_options(options, &uopt, true))
return -EINVAL; return -EINVAL;
...@@ -2095,6 +2099,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) ...@@ -2095,6 +2099,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
uopt.umask = 0; uopt.umask = 0;
uopt.fmode = UDF_INVALID_MODE; uopt.fmode = UDF_INVALID_MODE;
uopt.dmode = UDF_INVALID_MODE; uopt.dmode = UDF_INVALID_MODE;
uopt.nls_map = NULL;
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi) if (!sbi)
...@@ -2275,8 +2280,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) ...@@ -2275,8 +2280,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
iput(sbi->s_vat_inode); iput(sbi->s_vat_inode);
parse_options_failure: parse_options_failure:
#ifdef CONFIG_UDF_NLS #ifdef CONFIG_UDF_NLS
if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) if (uopt.nls_map)
unload_nls(sbi->s_nls_map); unload_nls(uopt.nls_map);
#endif #endif
if (lvid_open) if (lvid_open)
udf_close_lvid(sb); udf_close_lvid(sb);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册