Summary
Listing a cleartext directory of an opened filesystem triggers automatic conflict resolution. This mechanism can create duplicate directory links (i.e. dir.c9r files containing a prexisting directory-id), leading to DirIdCollision.java results in the health check.
Explanation
Cryptofs-Version: 2.10.0
Assume two users create a directory named "foo":
Cleartext | Ciphertext
---------------------------------
│ | ├ AA
│ | │ └ BBBBCCCC
└ foo | │ └ ciphertext.c9r
│ | │ └ dir.c9r
│ | └ QQ
│ | └ RRRRSSSS
└ ... | └ ...
The sync client or a script renames one directory link file to keep a valid state:
Cleartext | Ciphertext
---------------------------------
│ | ├ AA
│ | │ └ BBBBCCCC
│ | │ └ ciphertext_conflict.c9r /* not valid base64url name, hence skipped in listing */
│ | │ │ └ dir.c9r
└ foo | │ └ ciphertext.c9r
│ | │ └ dir.c9r
│ | └ QQ
│ | └ RRRRSSSS
└ ... | └ ...
The next time the parent of foo is listed, cryptofs lifts the suffix _conflict out of a ciphertext filename and pastes it into a cleartext name. But conflict resolution by renaming is only sound for files. The whole .c9r directory is moved verbatim — including its dir.c9r. The result is a second directory entry carrying the same directory ID, i.e. two cleartext folders backed by the identical d/XX/YYY… content dir.
Cleartext | Ciphertext
---------------------------------
│ | ├ AA
│ | │ └ BBBBCCCC
├ foo_conflict | │ └ c1ph3rt3xt.c9r /* not valid base64url name, hence skipped in listing */
│ │ | │ │ └ dir.c9r
└ foo | │ └ ciphertext.c9r
│ | │ └ dir.c9r
│ | └ QQ
│ | └ RRRRSSSS
└ ... | └ ...
There is no code path anywhere that assigns a fresh dir ID when a directory entry is renamed during conflict resolution.
There is a trivial conflict resolution (resolveConflictTrivially (:158-173)), where an identical dir.c9r deletes the conflicting copy. But the dir.c9r files might not be considered identical, eg. if during the comparsion the sync client has only created the new directory without writing dir.c9r.
Result
Two directories on the cleartext side with the same, synced content.
Summary
Listing a cleartext directory of an opened filesystem triggers automatic conflict resolution. This mechanism can create duplicate directory links (i.e. dir.c9r files containing a prexisting directory-id), leading to DirIdCollision.java results in the health check.
Explanation
Cryptofs-Version: 2.10.0
Assume two users create a directory named "foo":
The sync client or a script renames one directory link file to keep a valid state:
The next time the parent of
foois listed, cryptofs lifts the suffix_conflictout of a ciphertext filename and pastes it into a cleartext name. But conflict resolution by renaming is only sound for files. The whole .c9r directory is moved verbatim — including its dir.c9r. The result is a second directory entry carrying the same directory ID, i.e. two cleartext folders backed by the identical d/XX/YYY… content dir.There is no code path anywhere that assigns a fresh dir ID when a directory entry is renamed during conflict resolution.
There is a trivial conflict resolution (
resolveConflictTrivially (:158-173)), where an identical dir.c9r deletes the conflicting copy. But the dir.c9r files might not be considered identical, eg. if during the comparsion the sync client has only created the new directory without writing dir.c9r.Result
Two directories on the cleartext side with the same, synced content.