diff --git a/LoopbackFS-C/loopback/loopback.c b/LoopbackFS-C/loopback/loopback.c index dfc703f..af667ee 100644 --- a/LoopbackFS-C/loopback/loopback.c +++ b/LoopbackFS-C/loopback/loopback.c @@ -47,12 +47,6 @@ typedef unsigned int u_int; typedef unsigned long u_long; #endif -#define G_PREFIX "org" -#define G_KAUTH_FILESEC_XATTR G_PREFIX ".apple.system.Security" -#define A_PREFIX "com" -#define A_KAUTH_FILESEC_XATTR A_PREFIX ".apple.system.Security" -#define XATTR_APPLE_PREFIX "com.apple." - struct loopback { uint32_t blocksize; bool case_insensitive; @@ -759,19 +753,11 @@ loopback_setxattr(const char *path, const char *name, const char *value, int res; flags |= XATTR_NOFOLLOW; - if (!strncmp(name, XATTR_APPLE_PREFIX, sizeof(XATTR_APPLE_PREFIX) - 1)) { - flags &= ~(XATTR_NOSECURITY); - } - - if (!strcmp(name, A_KAUTH_FILESEC_XATTR)) { - - char new_name[MAXPATHLEN]; - - memcpy(new_name, A_KAUTH_FILESEC_XATTR, sizeof(A_KAUTH_FILESEC_XATTR)); - memcpy(new_name, G_PREFIX, sizeof(G_PREFIX) - 1); + if (strncmp(name, "com.apple.", 10) == 0) { + char new_name[MAXPATHLEN] = "org.apple."; + strncpy(new_name + 10, name + 10, sizeof(new_name) - 10); res = setxattr(path, new_name, value, size, position, flags); - } else { res = setxattr(path, name, value, size, position, flags); } @@ -789,15 +775,11 @@ loopback_getxattr(const char *path, const char *name, char *value, size_t size, { int res; - if (strcmp(name, A_KAUTH_FILESEC_XATTR) == 0) { - - char new_name[MAXPATHLEN]; - - memcpy(new_name, A_KAUTH_FILESEC_XATTR, sizeof(A_KAUTH_FILESEC_XATTR)); - memcpy(new_name, G_PREFIX, sizeof(G_PREFIX) - 1); + if (strncmp(name, "com.apple.", 10) == 0) { + char new_name[MAXPATHLEN] = "org.apple."; + strncpy(new_name + 10, name + 10, sizeof(new_name) - 10); res = getxattr(path, new_name, value, size, position, XATTR_NOFOLLOW); - } else { res = getxattr(path, name, value, size, position, XATTR_NOFOLLOW); } @@ -819,10 +801,10 @@ loopback_listxattr(const char *path, char *list, size_t size) char *curr = list; do { size_t thislen = strlen(curr) + 1; - if (strcmp(curr, G_KAUTH_FILESEC_XATTR) == 0) { - memmove(curr, curr + thislen, res - len - thislen); - res -= thislen; - break; + if (strncmp(curr, "com.apple.", 10) == 0) { + curr[0] = 'o'; + curr[1] = 'r'; + curr[2] = 'g'; } curr += thislen; len += thislen; @@ -850,15 +832,11 @@ loopback_removexattr(const char *path, const char *name) { int res; - if (strcmp(name, A_KAUTH_FILESEC_XATTR) == 0) { - - char new_name[MAXPATHLEN]; - - memcpy(new_name, A_KAUTH_FILESEC_XATTR, sizeof(A_KAUTH_FILESEC_XATTR)); - memcpy(new_name, G_PREFIX, sizeof(G_PREFIX) - 1); + if (strncmp(name, "com.apple.", 10) == 0) { + char new_name[MAXPATHLEN] = "org.apple."; + strncpy(new_name + 10, name + 10, sizeof(new_name) - 10); res = removexattr(path, new_name, XATTR_NOFOLLOW); - } else { res = removexattr(path, name, XATTR_NOFOLLOW); } diff --git a/LoopbackFS-ObjC/LoopbackFS/LoopbackFS.m b/LoopbackFS-ObjC/LoopbackFS/LoopbackFS.m index ff5d991..0888ad1 100644 --- a/LoopbackFS-ObjC/LoopbackFS/LoopbackFS.m +++ b/LoopbackFS-ObjC/LoopbackFS/LoopbackFS.m @@ -557,12 +557,6 @@ #pragma mark Extended Attributes -#define G_PREFIX "org" -#define G_KAUTH_FILESEC_XATTR G_PREFIX ".apple.system.Security" -#define A_PREFIX "com" -#define A_KAUTH_FILESEC_XATTR A_PREFIX ".apple.system.Security" -#define XATTR_APPLE_PREFIX "com.apple." - - (NSArray *)extendedAttributesOfItemAtPath:(NSString *)path error:(NSError **)error { NSString *p = [rootPath_ stringByAppendingString:path]; @@ -587,9 +581,10 @@ char *ptr = (char *)[data bytes]; while (ptr < (((char *)[data bytes]) + size)) { NSString *s = [NSString stringWithUTF8String:ptr]; - if (strcmp(ptr, G_KAUTH_FILESEC_XATTR) != 0) { - [contents addObject:s]; + if ([s hasPrefix:@"com.apple."]) { + s = [@"org.apple." stringByAppendingString: [s substringFromIndex:10]]; } + [contents addObject:s]; ptr += ([s length] + 1); } return contents; @@ -601,14 +596,11 @@ error:(NSError **)error { NSString *p = [rootPath_ stringByAppendingString:path]; - const char *n = [name UTF8String]; - if (strcmp(n, A_KAUTH_FILESEC_XATTR) == 0) { - char new_name[MAXPATHLEN]; - memcpy(new_name, A_KAUTH_FILESEC_XATTR, sizeof(A_KAUTH_FILESEC_XATTR)); - memcpy(new_name, G_PREFIX, sizeof(G_PREFIX) - 1); - n = new_name; + if ([name hasPrefix:@"com.apple."]) { + name = [@"org.apple." stringByAppendingString: [name substringFromIndex:10]]; } + const char *n = [name UTF8String]; ssize_t size = getxattr([p UTF8String], n, NULL, 0, (uint32_t)position, XATTR_NOFOLLOW); if (size < 0) { @@ -644,19 +636,12 @@ NSString *p = [rootPath_ stringByAppendingString:path]; + if ([name hasPrefix:@"com.apple."]) { + name = [@"org.apple." stringByAppendingString: [name substringFromIndex:10]]; + } + const char *n = [name UTF8String]; - if (strcmp(n, A_KAUTH_FILESEC_XATTR) == 0) { - char new_name[MAXPATHLEN]; - memcpy(new_name, A_KAUTH_FILESEC_XATTR, sizeof(A_KAUTH_FILESEC_XATTR)); - memcpy(new_name, G_PREFIX, sizeof(G_PREFIX) - 1); - n = new_name; - } - options |= XATTR_NOFOLLOW; - if (!strncmp(n, XATTR_APPLE_PREFIX, sizeof(XATTR_APPLE_PREFIX) - 1)) { - options &= ~(XATTR_NOSECURITY); - } - int ret = setxattr([p UTF8String], n, [value bytes], [value length], (uint32_t)position, options); if (ret == -1) { @@ -674,14 +659,11 @@ error:(NSError **)error { NSString *p = [rootPath_ stringByAppendingString:path]; - const char *n = [name UTF8String]; - if (strcmp(n, A_KAUTH_FILESEC_XATTR) == 0) { - char new_name[MAXPATHLEN]; - memcpy(new_name, A_KAUTH_FILESEC_XATTR, sizeof(A_KAUTH_FILESEC_XATTR)); - memcpy(new_name, G_PREFIX, sizeof(G_PREFIX) - 1); - n = new_name; + if ([name hasPrefix:@"com.apple."]) { + name = [@"org.apple." stringByAppendingString: [name substringFromIndex:10]]; } + const char *n = [name UTF8String]; int res = removexattr([p UTF8String], n, XATTR_NOFOLLOW); if (res == -1) { if (error) { diff --git a/LoopbackFS-Swift/LoopbackFS/LoopbackFS.swift b/LoopbackFS-Swift/LoopbackFS/LoopbackFS.swift index f0f018a..d245f53 100644 --- a/LoopbackFS-Swift/LoopbackFS/LoopbackFS.swift +++ b/LoopbackFS-Swift/LoopbackFS/LoopbackFS.swift @@ -297,7 +297,14 @@ public final class LoopbackFS: NSObject { // Extract attribute names: let list = data.split(separator: 0).compactMap { - String(data: Data($0), encoding: .utf8) + guard var name = String(data: Data($0), encoding: .utf8) else { + return nil as String? + } + if name.hasPrefix("com.apple.") { + name = "org.apple." + name[name.index(name.startIndex, offsetBy: 10)...] + } + + return name } return list } @@ -307,6 +314,10 @@ public final class LoopbackFS: NSObject { let originalUrl = URL(fileURLWithPath: rootPath.appending(path)) return try originalUrl.withUnsafeFileSystemRepresentation { fileSystemPath -> Data in + var name = name + if name.hasPrefix("com.apple.") { + name = "org.apple." + name[name.index(name.startIndex, offsetBy: 10)...] + } // Determine attribute size: let length = getxattr(fileSystemPath, name, nil, 0, UInt32(position), XATTR_NOFOLLOW) @@ -339,6 +350,11 @@ public final class LoopbackFS: NSObject { // TODO: Why is this necessary? let newOptions = options & ~(XATTR_NOSECURITY | XATTR_NODEFAULT) + var name = name + if name.hasPrefix("com.apple.") { + name = "org.apple." + name[name.index(name.startIndex, offsetBy: 10)...] + } + let result = value.withUnsafeBytes { setxattr(fileSystemPath, name, $0.baseAddress?.assumingMemoryBound(to: Int8.self), value.count, UInt32(position), newOptions | XATTR_NOFOLLOW) } @@ -350,6 +366,11 @@ public final class LoopbackFS: NSObject { let originalUrl = URL(fileURLWithPath: rootPath.appending(path)) try originalUrl.withUnsafeFileSystemRepresentation { fileSystemPath in + var name = name + if name.hasPrefix("com.apple.") { + name = "org.apple." + name[name.index(name.startIndex, offsetBy: 10)...] + } + let result = removexattr(fileSystemPath, name, XATTR_NOFOLLOW) guard result >= 0 else { throw NSError(posixErrorCode: errno) } }