Read from DMG from sandboxed app

Is it possible to read the files from a DMG from a sandboxed app?

I have tried using hdiutil using Process but always run in to the error "hdiutil: attach failed - Device not configured". I am running hdiutil attach -verbose -debug -mountroot /path/to/mount/ /path/to/dmg.dmg where both the mount root and DMG file have been chosen via an NSOpenPanel and support writing by the application.

I have also tried moving the DMG to a directory within the app's storage (as returned via FileManager.default.urls(for:in:)) and mounting it within the same directory but get the same error.

The full output is:

fileURL file:///path/to/dmg.dmg
directoryURL file:///path/to/mount/
calling DIHLDiskImageAttach with
debug: true
image-options:
quiet: false
mount-type: in
drive-options:
main-url: file:///path/to/dmg.dmg
mount-point: file:///path/to/mount/
verbose: true
agent: hdiutil
2020-07-28 17:24:35.848455+0100 hdiutil[15701:1369864] DIHLDiskImageAttach: input dictionary {
agent = hdiutil;
debug = 1;
"drive-options" = {
};
"image-options" = {
};
"main-url" = "file:///path/to/dmg.dmg";
"mount-point" = "file:///path/to/mount/";
"mount-type" = in;
quiet = 0;
verbose = 1;
}
2020-07-28 17:24:35.848677+0100 hdiutil[15701:1369864] DIHLDiskImageAttach: disabling legacy image format attach
2020-07-28 17:24:35.848700+0100 hdiutil[15701:1369864] DIHLDiskImageAttach: newImagekeys = {
"legacy-disabled" = 1;
}
2020-07-28 17:24:35.848729+0100 hdiutil[15701:1369864] DIHLDiskImageAttach: creating DIHelperProxy
2020-07-28 17:24:35.848769+0100 hdiutil[15701:1369864] with dictionary: {
agent = hdiutil;
debug = 1;
"drive-options" = {length = 42, bytes = 0x62706c69 73743030 d0080000 00000000 ... 00000000 00000009 };
"image-options" = {length = 65, bytes = 0x62706c69 73743030 d101025f 100f6c65 ... 00000000 0000001e };
"main-url" = "file:///path/to/dmg.dmg";
"mount-point" = "file:///path/to/mount/";
"mount-type" = in;
operation = DIHelperAttach;
quiet = 0;
verbose = 1;
}
2020-07-28 17:24:35.848787+0100 hdiutil[15701:1369864] [DIHelperProxy alloc]
2020-07-28 17:24:35.848815+0100 hdiutil[15701:1369864] [DIHelperProxy alloc] returning self 0x600002c0c480, retainCount 1
2020-07-28 17:24:35.852410+0100 hdiutil[15701:1369864] DIHLDiskImageAttach: running DIHelperProxy
2020-07-28 17:24:35.852426+0100 hdiutil[15701:1369864] [DIHelperProxy performOperationReturning] entry
2020-07-28 17:24:35.852438+0100 hdiutil[15701:1369864] [DIHelperProxy performOperationReturning] detaching thread
2020-07-28 17:24:35.852675+0100 hdiutil[15701:1369867] [DIHelperProxy workerThread] entry
2020-07-28 17:24:35.852696+0100 hdiutil[15701:1369867] [DIHelperProxy workerThread] setting up server
2020-07-28 17:24:35.852706+0100 hdiutil[15701:1369867] [DIHelperProxy threadSetupServer] entry
2020-07-28 17:24:35.852737+0100 hdiutil[15701:1369867] [DIHelperProxy threadSetupServer] Cannot start hdiejectd because app is sandboxed
2020-07-28 17:24:35.852750+0100 hdiutil[15701:1369867] [DIHelperProxy threadSetupServer] exiting
2020-07-28 17:24:35.852759+0100 hdiutil[15701:1369867] error: unable to set up framework server.
2020-07-28 17:24:35.852767+0100 hdiutil[15701:1369867] [DIHelperProxy workerThread] waiting for task to terminate to avoid zombies
2020-07-28 17:24:35.852775+0100 hdiutil[15701:1369867] checkHelperStatusWaitingForExit: no helper process, skipping
2020-07-28 17:24:35.852783+0100 hdiutil[15701:1369867] [DIHelperProxy workerThread] helper exited
2020-07-28 17:24:35.852793+0100 hdiutil[15701:1369867] [DIHelperProxy workerThread] exiting
2020-07-28 17:24:35.852824+0100 hdiutil[15701:1369864] [DIHelperProxy performOperationReturning] returning 6
2020-07-28 17:24:35.852847+0100 hdiutil[15701:1369864] DIHLDiskImageAttach: DIHelperProxy returned 6
2020-07-28 17:24:35.852860+0100 hdiutil[15701:1369864] [DIHelperProxy dealloc]
DIHLDiskImageAttach() returned 6
(null)
hdiutil: attach failed - Device not configured


The issue appears to be "Cannot start hdiejectd because app is sandboxed", does this mean it's not possible to read a DMG in a sandboxed app, or is there another method available?

Replies

I've done this before from a sandboxed app, but it was distributed via Developer ID (not the Mac App Store). If you create an XPC service which has no entitlements, you can do your work there.

The issue appears to be "Cannot start hdiejectd because app is sandboxed"

Right. Mounting a disk image requires that the process be able to communicate with the various XPC services advertised by the hdiejectd daemon (see /System/Library/LaunchDaemons/com.apple.hdiejectd.plist). As a rule sandboxed apps are not allowed to communicate with arbitrary XPC services; if the service isn’t on the sandbox’s allowlist, you can’t talk to it.

If you’re planning to ship outside of the Mac App Store, you can punch your way through the sandbox using various techniques (for example, the one suggested by TyngJJ). However, if you intend to ship in the store, such techniques are unlikely to pass App Review.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
An XPC service does work, I assume because it's not sandboxed.

As Quinn mentions, this seems unlikely to pass App Review.

Reading from a DMG is a core part of my app and I would like to distribute via the Mac App Store. Is there any way to have this validated before building the full product?

I'm guessing this sort of use-case is why some apps require a helper app to be (manually) downloaded to provide some functionality. Would this be the recommended route to take?
@Joseph : Did you find any solution to this issue, I am having similar requirement. Looking for the solution.
Add a Comment

I am having similar requirement

See my response in the other thread you commented on.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"