Skip to content

Commit

Permalink
Ensure sdk directory has no file protections (#217)
Browse files Browse the repository at this point in the history
Without this, apps that set the protection entitlement of
`NSURLFileProtectionNone` are likely to crash when the device is locked
  • Loading branch information
Reflejo authored Feb 10, 2025
1 parent 6a5b8b7 commit 341a8f6
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 2 deletions.
2 changes: 2 additions & 0 deletions examples/swift/hello_world/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ swift_library(
ios_application(
name = "ios_app",
bundle_id = "io.bitdrift.example.helloworld",
entitlements = "Protected.entitlements",
families = [
"iphone",
"ipad",
Expand Down Expand Up @@ -66,6 +67,7 @@ swift_library(
ios_application(
name = "hello_world_app",
bundle_id = "io.bitdrift.example.helloworld",
entitlements = "Protected.entitlements",
families = [
"iphone",
"ipad",
Expand Down
8 changes: 8 additions & 0 deletions examples/swift/hello_world/Protected.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.default-data-protection</key>
<string>NSFileProtectionComplete</string>
</dict>
</plist>
33 changes: 33 additions & 0 deletions platform/swift/source/LoggerBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@ import Foundation

typealias LoggerID = Int64

/// Creates the directory we'll use for the SDK's ring buffer and other storage files,
/// and disables file protection on it to prevent the app from crashing with EXEC_BAD_ACCESS
/// when the device is locked. Failing to set the protection policy on the directory will result
/// in a nil logger.
///
/// - parameter path: The path to be created and/or set to none protection
private func makeDirectoryAndDisableProtection(at path: String) throws {
let url = NSURL(fileURLWithPath: path)
let manager = FileManager.default
if !manager.fileExists(atPath: path) {
try manager.createDirectory(
atPath: path,
withIntermediateDirectories: true,
attributes: [FileAttributeKey.protectionKey: FileProtectionType.none]
)
return
}

var fileProtection: AnyObject?
try url.getResourceValue(&fileProtection, forKey: .fileProtectionKey)
if let protection = fileProtection as? FileProtectionType, protection != .none {
try url.setResourceValue(FileProtectionType.none, forKey: .fileProtectionKey)
}
}

/// A wrapper around Rust logger ID that makes it possible to call Rust logger methods.
/// It shutdowns underlying Rust logger on release.
final class LoggerBridge: LoggerBridging {
Expand All @@ -30,6 +55,14 @@ final class LoggerBridge: LoggerBridging {
network: Network?,
errorReporting: RemoteErrorReporting
) {
do {
try bufferDirectoryPath.map(makeDirectoryAndDisableProtection(at:))
} catch {
// To be safe we don't initialize the logger if we can't create the directory or set
// the file protection policy.
return nil
}

let loggerID = capture_create_logger(
bufferDirectoryPath,
apiKey,
Expand Down
2 changes: 0 additions & 2 deletions platform/swift/source/ObjCWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
// LICENSE file or at:
// https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt

#import <UIKit/UIKit.h>

@interface ObjCWrapper: NSObject

/**
Expand Down

0 comments on commit 341a8f6

Please sign in to comment.