iCloud Drive, like the Finder into which it tries to merge, is a lot more complex than might appear. In trying to get a better understanding of its handling of extended attributes (xattrs), I have been looking at some of its complex behaviours, and thought my observations might be of interest to others.
iCloud Drive has two user modes
I don’t recall seeing this made clear anywhere, but iCloud Drive behaves quite differently when copying or moving files with only one client computer, compared to when those files are accessed by more than one client.
However a single Mac (or Windows client, if you will) accesses its iCloud storage, iCloud doesn’t change the content of files. Extended attributes are preserved, even if obviously bogus, none are added as tags, and what you get back is what you put there in the first place. This also applies to files which are manipulated in iCloud, for example documents which are edited there, or archives which are decompressed in place.
This ensures that when you use iCloud as a storage extension, or substitute, for your Mac, it works just the same as local storage. If you know of any exceptions to that, I’d be very interested to hear of them.
iCloud keeps track of which files originate from which client
When you access your iCloud Drive from two or more client systems, iCloud Drive knows which files originated from each of the clients, and keeps track of that. It does that as part of its mechanism to handle version conflicts which can arise, for example, when the same file is being modified by two different clients, as described here.
This also applies when the files are created or changed in iCloud. Decompressing a Zip archive in your iCloud Drive, for example, leaves the decompressed files marked as to which client decompressed them.
This is important, because it determines how those files are handled when a client accesses them.
iCloud handles files differently when they are accessed from another client
The simple model for this is copying or moving files from Mac A onto iCloud Drive, then accessing those files from Mac B, including copying them to local storage on Mac B. Unlike single client access, iCloud presents the second client (Mac B) with files which may well be different from those seen simultaneously by the originating client (Mac A).
First, iCloud Drive filters all the extended attributes of every file which it can ‘see’ directly. It doesn’t open files, like Zip archives, to peek inside, but does access all the folders and files within bundles, such as applications and libraries.
The only xattrs which it will pass on to the second client are Apple’s own, with types starting with
com.apple. I have not seen any third-party xattrs which have survived passage through iCloud’s filters. If you know of any, please let me know. This ensures that any documents which rely on third-party xattrs, such as Skim’s annotated PDFs, are rendered useless (Skim ingeniously stores all annotations as xattrs, so as not to tamper with the contents of the original PDF).
Second, iCloud Drive may add xattrs to certain files. I think that I have caught it adding a
com.apple.FinderInfo xattr to one file, but haven’t been able to reproduce that.
What is most startling is the way that it adds an apparently unique xattr of type
com.apple.cscachefs to many files within application bundles. iCloud Drive doesn’t appear to add quarantine flags (
com.apple.quarantine), but adds
com.apple.cscachefs instead – only when accessed from a second client.
Which xattrs get stripped?
iCloud Drive also strips
com.apple.* type xattrs according to quite complex heuristics. To determine which get removed, the xattrs are not opened; it is perfectly possible to pass inappropriate binary data in xattrs which should contain only text, or larger amounts of inappropriate binary data in xattrs which should be of fixed, small size.
com.apple.* xattrs, like
com.apple.serverdocs.markup, always get stripped; others will only be stripped if they exceed a certain size, which varies according to the type of xattr. All xattrs of 80 KB or larger are removed, but iCloud allows
com.apple.metadata:kMDItemCopyright, for example, to reach 24 KB size and leaves it intact. If you rely on a particular xattr passing unscathed through iCloud’s filters, you need to test it carefully over a range of sizes and situations.
Here are some of my test xattrs seen before being filtered by iCloud:
When downloaded to (or viewed from) a second client, this is all that remains of them:
I wish I knew! As far as I can tell it is a xattr type unique to Apple, and only added to certain files when they are passed from an originating client Mac A to a second client Mac B via iCloud Drive (or using a similar iCloud process). They have binary content (but not a binary property list) of 70 bytes fixed size, which contains no evident string data.
They are attached to the executable code and other files of size within application bundles. They are not attached to smaller property lists, signatures, folders, or similar, within the bundle. Because xattrs are not included in Gatekeeper’s signature checks, they do not affect app execution, nor do they appear to result in any other behaviour on a Mac. Once attached, they remain, unless deliberately removed by the user.
Their name appears to be a compound of Core Services, cache, and File System, and may be a marker for special handling within iCloud storage. If you know any more, I’d be most interested to hear, please.
Why does iCloud do all this?
I can only presume that these measures are intended to prevent potential spread of xattr-based malware or obfuscated content between Macs using iCloud. If you have any better ideas, I’d love to hear them.
What can you do about it?
To avoid xattr stripping and the addition of
com.apple.cscachefs, pass iCloud archives or other prepared versions of apps or other files. It currently makes no attempt to tamper with their contents, or even add a quarantine flag.