1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
#include "apple_xattr_workaround.h"
#ifdef __APPLE__
#include <errno.h>
#include <string.h>
#include <sys/xattr.h>
namespace securefs
{
static const char APPLE_FINDER_INFO[] = "com.apple.FinderInfo";
static const char REPLACEMENT_FOR_FINDER_INFO[] = "_securefs.FinderInfo";
static const char APPLE_QUARANTINE[] = "com.apple.quarantine";
static_assert(sizeof(APPLE_FINDER_INFO) == sizeof(REPLACEMENT_FOR_FINDER_INFO),
"The two \"FinderInfo\" attribute names must have the same size");
void transform_listxattr_result(char* buffer, size_t size)
{
if (size < sizeof(APPLE_FINDER_INFO))
return;
for (size_t i = 0; i <= size - sizeof(APPLE_FINDER_INFO); ++i)
{
if (i > 0 && buffer[i - 1] != '\0')
{
continue; // Not a string boundary.
}
// The terminating null must be compared too.
if (memcmp(buffer + i, REPLACEMENT_FOR_FINDER_INFO, sizeof(REPLACEMENT_FOR_FINDER_INFO))
== 0)
{
memcpy(buffer + i, APPLE_FINDER_INFO, sizeof(APPLE_FINDER_INFO));
}
}
}
static int precheck_common(const char** name)
{
if (strcmp(*name, APPLE_FINDER_INFO) == 0)
{
*name = REPLACEMENT_FOR_FINDER_INFO;
return 1; // No early return.
}
if (strcmp(*name, REPLACEMENT_FOR_FINDER_INFO) == 0)
{
return -EPERM;
}
return 1;
}
int precheck_getxattr(const char** name)
{
if (strcmp(*name, APPLE_QUARANTINE) == 0)
{
return -ENOATTR;
}
return precheck_common(name);
}
int precheck_setxattr(const char** name, int* flags)
{
if (strcmp(*name, APPLE_QUARANTINE) == 0)
{
return 0; // Fakes success of quarantine to work around "XXX is damaged" bug on macOS.
}
if (strcmp(*name, APPLE_FINDER_INFO) == 0)
{
*name = REPLACEMENT_FOR_FINDER_INFO;
*flags &= ~(unsigned)XATTR_NOSECURITY;
return 1; // No early return.
}
if (strcmp(*name, REPLACEMENT_FOR_FINDER_INFO) == 0)
{
return -EPERM;
}
return 1;
}
int precheck_removexattr(const char** name) { return precheck_common(name); }
} // namespace securefs
#endif
|