ANDROID: sdcardfs: Switch to internal case insensitive compare
authorDaniel Rosenberg <drosen@google.com>
Thu, 9 Mar 2017 01:20:02 +0000 (17:20 -0800)
committerAmit Pundir <amit.pundir@linaro.org>
Mon, 10 Apr 2017 07:42:16 +0000 (13:12 +0530)
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 e6f8e9edf8a96d4b8569f3d2eac6fe24fa269fb1..64494a50e2507e835b0d86231d83fa2848a8ab85 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;
        }
@@ -166,7 +162,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 c0d5a9d72bdefc1deffd93910b92a8e4864684da..925692f0d20c8db03cc6485845366c59089000d0 100644 (file)
@@ -282,7 +282,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_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 (d_inode(child)) {
                                        get_derived_permission(dentry, child);
                                        fixup_tmp_permissions(d_inode(child));
index 56d643f4a9ee134bb88410b72c1ac0a58f51cec3..68f8f45716151b7538374e73421bd651fac94b3f 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 042f989f0bea2f398bd01ed1aa22789e1e9667f8..0778eb063b63c0d890daf0c5acb2c3c038d7fb27 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;
 };
 
@@ -612,6 +611,11 @@ 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);