diff options
| author | Gabriel Krisman Bertazi <krisman@suse.de> | 2026-07-31 15:54:45 -0400 |
|---|---|---|
| committer | Gabriel Krisman Bertazi <krisman@suse.de> | 2026-07-31 16:33:14 -0400 |
| commit | a511442085c140da9cdbe60e3f0fab1c71480801 (patch) | |
| tree | c0a53455e81788221f48f78bdde06667bdcfc1f7 | |
| parent | 080241946ec542ada349fced93936e2aebb51c75 (diff) | |
unicode: Properly reject invalid encoding version strings
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 <krisman@suse.de>
| -rw-r--r-- | fs/unicode/utf8-core.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/unicode/utf8-core.c b/fs/unicode/utf8-core.c index 8c4b8e27e956..f313532f5e80 100644 --- a/fs/unicode/utf8-core.c +++ b/fs/unicode/utf8-core.c @@ -204,17 +204,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); |
