Skip to content
This repository has been archived by the owner on Jul 3, 2019. It is now read-only.

Commit

Permalink
ANDROID: sdcardfs: Fix sdcardfs to stop creating cases-sensitive dupl…
Browse files Browse the repository at this point in the history
…icate entries.

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 <[email protected]>
bug: 75987238
Signed-off-by: Nathan Chancellor <[email protected]>
  • Loading branch information
Ritesh Harjani authored and nathanchance committed Apr 13, 2018
1 parent 52d73bc commit e252f35
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion fs/sdcardfs/sdcardfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit e252f35

Please sign in to comment.