From 213bbba1fb98bd91c4e993fb00e9d9fb07c3a4b1 Mon Sep 17 00:00:00 2001 From: Konstantin Germanov Date: Sat, 2 Nov 2019 05:31:10 -0400 Subject: [PATCH] CIFS: Fix file access error with surrogate pair in the file names at case of 'nocase' option Fix it by use raw bytes to hash if we can't convert the character [Steps to Reproduce for bug] client# mount //X.X.X.X/C\$ /tmp/test -o 'username=*,pass=*' client# touch /tmp/test/$(echo -e '\xf0\x9d\x9f\xa3') client# umount /tmp/test client# mount //X.X.X.X/C\$ /tmp/test -o 'username=*,pass=*,nocase' client# ls -1i /tmp/test /bin/ls: cannot access '/tmp/test/1': Invalid argument ? 1 BugLink: https://bugzilla.samba.org/show_bug.cgi?id=14186 Signed-off-by: Konstantin Germanov CC: Stable --- fs/cifs/dir.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index e98e24eaa6a8..75e754fc4538 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -901,10 +901,12 @@ static int cifs_ci_hash(const struct dentry *dentry, struct qstr *q) hash = init_name_hash(dentry); for (i = 0; i < q->len; i += charlen) { charlen = codepage->char2uni(&q->name[i], q->len - i, &c); - /* error out if we can't convert the character */ - if (unlikely(charlen < 0)) - return charlen; - hash = partial_name_hash(cifs_toupper(c), hash); + /* use raw bytes if we can't convert the character */ + if (unlikely(charlen < 0)) { + hash = partial_name_hash(q->name[i], hash); + charlen = 1; + } else + hash = partial_name_hash(cifs_toupper(c), hash); } q->hash = end_name_hash(hash); @@ -937,7 +939,7 @@ static int cifs_ci_compare(const struct dentry *dentry, * be 1 byte long and compare the original byte. */ if (unlikely(l1 < 0 && l2 < 0)) { - if (str[i] != name->name[i]) + if (str[i] != (char)name->name[i]) return 1; l1 = 1; continue; -- 2.11.0