ANDROID: sdcardfs: Switch to internal case insensitive compare
authorDaniel Rosenberg <drosen@google.com>
Thu, 9 Mar 2017 01:20:02 +0000 (17:20 -0800)
committerStricted <info@stricted.net>
Thu, 11 Oct 2018 16:03:28 +0000 (18:03 +0200)
There were still a few places where we called into a case
insensitive lookup that was not defined by sdcardfs.
Moving them all to the same place will allow us to switch
the implementation in the future.

Additionally, the check in fixup_perms_recursive did not
take into account the length of both strings, causing
extraneous matches when the name we were looking for was
a prefix of the child name.

Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: I45ce768cd782cb4ea1ae183772781387c590ecc2

fs/sdcardfs/dentry.c
fs/sdcardfs/derived_perm.c
fs/sdcardfs/packagelist.c
fs/sdcardfs/sdcardfs.h

index f03f16d3e69df7387c816c64bd524645a4e15de6..4e9d2249e129a029a90a90bb891533662216567d 100644 (file)
@@ -82,11 +82,7 @@ static int sdcardfs_d_revalidate(struct dentry *dentry, unsigned int flags)
                spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
        }
 
-       if (dentry->d_name.len != lower_dentry->d_name.len) {
-               __d_drop(dentry);
-               err = 0;
-       } else if (strncasecmp(dentry->d_name.name, lower_dentry->d_name.name,
-                               dentry->d_name.len) != 0) {
+       if (!qstr_case_eq(&dentry->d_name, &lower_dentry->d_name)) {
                __d_drop(dentry);
                err = 0;
        }
@@ -167,7 +163,7 @@ static int sdcardfs_cmp_ci(const struct dentry *parent,
        }
        */
        if (name->len == len) {
-               if (strncasecmp(name->name, str, len) == 0)
+               if (str_n_case_eq(name->name, str, len))
                        return 0;
        }
        return 1;
index cdf31c95199ebe5a4147434b35a82d606e9ba790..f9232b1d97c61d7b8c3b9baf10ef2fec9792fb48 100644 (file)
@@ -274,7 +274,7 @@ static void __fixup_perms_recursive(struct dentry *dentry, struct limit_search *
        if (needs_fixup(info->perm)) {
                list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) {
                        spin_lock_nested(&child->d_lock, depth + 1);
-                       if (!(limit->flags & BY_NAME) || !strncasecmp(child->d_name.name, limit->name, limit->length)) {
+                       if (!(limit->flags & BY_NAME) || qstr_case_eq(&child->d_name, &limit->name)) {
                                if (child->d_inode) {
                                        get_derived_permission(dentry, child);
                                        fixup_tmp_permissions(child->d_inode);
index 21eb2d317e449c9aa54d60a432cecd89625f78ad..490dd97028fd4c82f316a20a23df2d6d7e7b7639 100644 (file)
@@ -251,8 +251,7 @@ static void fixup_all_perms_name(const struct qstr *key)
        struct sdcardfs_sb_info *sbinfo;
        struct limit_search limit = {
                .flags = BY_NAME,
-               .name = key->name,
-               .length = key->len,
+               .name = QSTR_INIT(key->name, key->len),
        };
        list_for_each_entry(sbinfo, &sdcardfs_super_list, list) {
                if (sbinfo_has_sdcard_magic(sbinfo))
@@ -265,8 +264,7 @@ static void fixup_all_perms_name_userid(const struct qstr *key, userid_t userid)
        struct sdcardfs_sb_info *sbinfo;
        struct limit_search limit = {
                .flags = BY_NAME | BY_USERID,
-               .name = key->name,
-               .length = key->len,
+               .name = QSTR_INIT(key->name, key->len),
                .userid = userid,
        };
        list_for_each_entry(sbinfo, &sdcardfs_super_list, list) {
index fe121e81a24d4ee7b02ca8628df7451ef97fb5b6..00bbfd6f8ddcdb867f117162b0913c8468de2c97 100644 (file)
@@ -470,8 +470,7 @@ extern void packagelist_exit(void);
 #define BY_USERID      (1 << 1)
 struct limit_search {
        unsigned int flags;
-       const char *name;
-       size_t length;
+       struct qstr name;
        userid_t userid;
 };
 
@@ -613,6 +612,10 @@ static inline bool str_case_eq(const char *s1, const char *s2)
        return !strcasecmp(s1, s2);
 }
 
+static inline bool str_n_case_eq(const char *s1, const char *s2, size_t len) {
+       return !strncasecmp(s1, s2, len);
+}
+
 static inline bool qstr_case_eq(const struct qstr *q1, const struct qstr *q2)
 {
        return q1->len == q2->len && str_case_eq(q1->name, q2->name);