ANDROID: sdcardfs: Fix sdcardfs to stop creating cases-sensitive duplicate entries.
authorRitesh Harjani <riteshh@codeaurora.org>
Mon, 19 Mar 2018 10:19:54 +0000 (15:49 +0530)
committerDaniel Rosenberg <drosen@google.com>
Sat, 7 Apr 2018 00:05:26 +0000 (17:05 -0700)
sdcardfs_name_match gets a 'name' argument from the underlying FS.
This need not be null terminated string.
So in sdcardfs_name_match -> qstr_case_eq -> we should use
str_n_case_eq.

This happens because few of the entries in lower level FS may not be
NULL terminated and may have some garbage characters passed while
doing sdcardfs_name_match.

For e.g.
 # dmesg |grep Download
 [  103.646386] sdcardfs_name_match: q1->name=.nomedia, q1->len=8,
 q2->name=Download\x17\x80\x03, q2->len=8
 [  104.021340] sdcardfs_name_match: q1->name=.nomedia, q1->len=8,
 q2->name=Download\x17\x80\x03, q2->len=8
 [  105.196864] sdcardfs_name_match: q1->name=.nomedia, q1->len=8,
 q2->name=Download\x17\x80\x03, q2->len=8
 [  109.113521] sdcardfs_name_match: q1->name=logs, q1->len=4,
 q2->name=Download\x17\x80\x03, q2->len=8

Now when we try to create a directory with different case for a such
files. SDCARDFS creates a entry if it could not find the underlying
entry in it's dcache.

To reproduce:-
1. bootup the device wait for some time after sdcardfs mounting to
   complete.
2. cd /storage/emulated/0
3. echo 3 > /proc/sys/vm/drop_caches
4. mkdir download

We now start seeing two entries with name.
Download & download.

Change-Id: I976d92a220a607dd8cdb96c01c2041c5c2bc3326
Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
bug: 75987238

fs/sdcardfs/sdcardfs.h

index 610466ad153d451198d66e82995bf3e5fe5b1bed..826afb5c7e88360a42f7dff18879851b76440f9a 100644 (file)
@@ -669,7 +669,7 @@ static inline bool str_n_case_eq(const char *s1, const char *s2, size_t 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);
+       return q1->len == q2->len && str_n_case_eq(q1->name, q2->name, q2->len);
 }
 
 #define QSTR_LITERAL(string) QSTR_INIT(string, sizeof(string)-1)