Casefolding filesystems can request a specific version of UTF-8 at mount-time. utf8_parse_version then assembles the "major.minor.rev" string into an unsigned int. There were two issues with the parser logic: first, individual fields are read as signed int, allowing negative numbers, second, an overflowed field will result in unexpected results. Something like the below actually succeeds to mount using utf8-12.1.0. mount -t tmpfs -o casefold=utf8-12.0.256 none /mnt [ 10.867859] tmpfs: Using encoding : utf8-12.1.0 Signed-off-by: Gabriel Krisman Bertazi --- fs/unicode/utf8-core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/unicode/utf8-core.c b/fs/unicode/utf8-core.c index 543c60c12461..c0a41b712e42 100644 --- a/fs/unicode/utf8-core.c +++ b/fs/unicode/utf8-core.c @@ -226,17 +226,19 @@ int utf8_parse_version(char *version) substring_t args[3]; unsigned int maj, min, rev; static const struct match_token token[] = { - {1, "%d.%d.%d"}, + {1, "%u.%u.%u"}, {0, NULL} }; if (match_token(version, token, args) != 1) return -EINVAL; - if (match_int(&args[0], &maj) || match_int(&args[1], &min) || - match_int(&args[2], &rev)) + if (match_uint(&args[0], &maj) || match_uint(&args[1], &min) || + match_uint(&args[2], &rev)) return -EINVAL; + if (maj > U8_MAX || min > U8_MAX || rev > U8_MAX) + return -EINVAL; return UNICODE_AGE(maj, min, rev); } EXPORT_SYMBOL(utf8_parse_version); -- 2.55.0