Commit 99bfa7bc authored by Jan Kara's avatar Jan Kara Committed by Greg Kroah-Hartman

udf: Allow mounting volumes with incorrect identification strings

commit b54e41f5 upstream.

Commit c26f6c61 ("udf: Fix conversion of 'dstring' fields to UTF8")
started to be more strict when checking whether converted strings are
properly formatted. Sudip reports that there are DVDs where the volume
identification string is actually too long - UDF reports:

[  632.309320] UDF-fs: incorrect dstring lengths (32/32)

during mount and fails the mount. This is mostly harmless failure as we
don't need volume identification (and even less volume set
identification) for anything. So just truncate the volume identification
string if it is too long and replace it with 'Invalid' if we just cannot
convert it for other reasons. This keeps slightly incorrect media still
mountable.

CC: stable@vger.kernel.org
Fixes: c26f6c61 ("udf: Fix conversion of 'dstring' fields to UTF8")
Reported-and-tested-by: default avatarSudip Mukherjee <sudipm.mukherjee@gmail.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarSudip Mukherjee <sudipm.mukherjee@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 097c13e1
...@@ -922,16 +922,20 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) ...@@ -922,16 +922,20 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
} }
ret = udf_dstrCS0toUTF8(outstr, 31, pvoldesc->volIdent, 32); ret = udf_dstrCS0toUTF8(outstr, 31, pvoldesc->volIdent, 32);
if (ret < 0) if (ret < 0) {
goto out_bh; strcpy(UDF_SB(sb)->s_volume_ident, "InvalidName");
pr_warn("incorrect volume identification, setting to "
strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret); "'InvalidName'\n");
} else {
strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret);
}
udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident); udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident);
ret = udf_dstrCS0toUTF8(outstr, 127, pvoldesc->volSetIdent, 128); ret = udf_dstrCS0toUTF8(outstr, 127, pvoldesc->volSetIdent, 128);
if (ret < 0) if (ret < 0) {
ret = 0;
goto out_bh; goto out_bh;
}
outstr[ret] = 0; outstr[ret] = 0;
udf_debug("volSetIdent[] = '%s'\n", outstr); udf_debug("volSetIdent[] = '%s'\n", outstr);
......
...@@ -341,6 +341,11 @@ static int udf_name_to_CS0(uint8_t *ocu, int ocu_max_len, ...@@ -341,6 +341,11 @@ static int udf_name_to_CS0(uint8_t *ocu, int ocu_max_len,
return u_len; return u_len;
} }
/*
* Convert CS0 dstring to output charset. Warning: This function may truncate
* input string if it is too long as it is used for informational strings only
* and it is better to truncate the string than to refuse mounting a media.
*/
int udf_dstrCS0toUTF8(uint8_t *utf_o, int o_len, int udf_dstrCS0toUTF8(uint8_t *utf_o, int o_len,
const uint8_t *ocu_i, int i_len) const uint8_t *ocu_i, int i_len)
{ {
...@@ -349,9 +354,12 @@ int udf_dstrCS0toUTF8(uint8_t *utf_o, int o_len, ...@@ -349,9 +354,12 @@ int udf_dstrCS0toUTF8(uint8_t *utf_o, int o_len,
if (i_len > 0) { if (i_len > 0) {
s_len = ocu_i[i_len - 1]; s_len = ocu_i[i_len - 1];
if (s_len >= i_len) { if (s_len >= i_len) {
pr_err("incorrect dstring lengths (%d/%d)\n", pr_warn("incorrect dstring lengths (%d/%d),"
s_len, i_len); " truncating\n", s_len, i_len);
return -EINVAL; s_len = i_len - 1;
/* 2-byte encoding? Need to round properly... */
if (ocu_i[0] == 16)
s_len -= (s_len - 1) & 2;
} }
} }
......
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