Error `sandbox_extension_issue_file` when resolving security-scoped bookmark of file under `/System/Volumes/Data/...`

I'm getting a sandbox_extension_issue_file error [1: Operation not permitted] from ScopedBookmarkAgent while trying to resolve a successfully created security-scoped bookmark via URL(resolvingBookmarkData:options:relativeTo:bookmarkDataIsStale:) which then produces the error

Error Domain=NSCocoaErrorDomain Code=256 "Couldn't issue sandbox extension for the resolved URL"

The error only occurs for files under a dedicated folder /System/Volumes/Data/Test and not for files and folders under, e.g., /Users/...

From what I understand, everything at /System/Volumes/Data/ and below should be accessible for the user.

I've made sure that the Test folder has read and write permissions for the current user and changed ownership of the folder to username:staff, where username denotes my local user name.

This happens both under macOS Big Sur 11.6.2 and macOS Monterey 12.1.

Any help is much appreciated!

Replies

Just a guess:

Since /System/Volumes/Data/ contents are merged into /, you need to replace those paths accordingly (i.e. replace that long prefer in a path with the root path), and then you'll probably get permission.

If that works, then I suspect that the Sandbox path access validation code has not been updated to match these aliased paths when volume groups were introduced. I've run into several related issues, outside sandbox, and need to employ similar work-arounds.

One would hope that Apple would provide APIs for determining the members and paths of volume groups, and conversion methods, but that's not happening (see also https://stackoverflow.com/q/63876549/43615)

Oh, and if you don't like the path replacement method, you could also try getting the CanonicalPath instead - that should also point to the regular path, but take more time than the simple string replacement. If you only do this for a few bookmarks, that shouldn't have an impact and is safer.

In fact, there are two ways I use in my apps to get the canonical path. I don't remember which one works, so try them both:

  1. Get the fileReferenceURL

  2. This code (see also https://stackoverflow.com/questions/64720189):

NSString* canonicalFilePath (NSURL *url)
{
	// Caution: Will expand /var/ into /private/var/
	NSString *result = nil;
	if (@available(macOS 10.12, *)) {
		NSString *cpath;
		if ([url getResourceValue:&cpath forKey:NSURLCanonicalPathKey error:nil] && cpath) {
			result = cpath;
		} else {
			result = url.URLByResolvingSymlinksInPath.path;
		}
	} else {
		result = [[url fileReferenceURL] filePathURL].path;
	}
	return result;
}

Thanks for your reply!

I've tried both methods, unfortunately without success. The canonical path method did not resolve /System/Volumes/Data/Test/ to /Test/ and the string replacement results in error

Domain=NSCocoaErrorDomain Code=260 "Scoped bookmarks can only be created for existing files or directories"

How did you get access to that URL in the first place? That is, where did the security-scoped bookmark come from?

Share and Enjoy

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

It's either from a URL that stems from an NSOpenPanel or the result of a drag and drop operation.

var bookmarkData: Data?
let openPanel = NSOpenPanel()
openPanel.canChooseFiles = false
openPanel.canChooseDirectories = true

if openPanel.runModal() == NSApplication.ModalResponse.OK {
    guard let url = openPanel.urls.first else {
        return
    }
    do {
        bookmarkData = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
    } catch {
        NSApplication.shared.presentError(error)
    }
}

Trying to resolve the successfully obtained bookmark via the aforementioned URL initializer fails:

var isStale = false
let url = try URL(resolvingBookmarkData: bookmarkData, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale)

It's also possible to reproduce this issue with an example project I've created for a previously reported sandbox-related issue: https://github.com/fheidenreich/sandbox-fat32-rename

  1. Choose, e.g., /System/Volumes/Data/Test/ via the "Select..." button.
  2. Press "Create test file" to see the error occur.

As some background: I've not randomly tried to break things, but got a report from a user of my app describing this issue. Apparently, migration assistant created a new folder /System/Volumes/Data/Data/ when moving to Monterey where all the files reside which he tries to edit using my app.

It's of course possible to move the data to the User's folder, but I wanted to at least gather some understanding of the underlying issue and possibly prevent this from happening again.

Thanks for your reply!

It's either from a URL that stems from an NSOpenPanel or the result of a drag and drop operation.

OK.

If you access that URL directly, before creating the bookmark, does that work? It’s security scoped, so you’ll need to surround it with the usual startAccessingSecurityScopedResource() / stopAccessingSecurityScopedResource() pair.

Share and Enjoy

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

Yes, accessing the URL directly works — thanks for the workaround! I'd then need to add some extra machinery to store "per-session" security-scoped URLs that cannot be persisted using security-scoped bookmarks.

FYI, NSDocumentController.noteNewRecentDocumentURL() also gives a sandbox error for the URL.

Can you provide any details on the underlying reasons for this behavior? Is it also to be expected in other circumstances?

Yes, accessing the URL directly works

OK.

Can you provide any details on the underlying reasons for this behavior?

No. My earlier question wasn’t really intended as a workaround but rather as a diagnostic test. I’ve no idea what’s causing the underlying issue )-:

Accessing the data volume directly in this way is somewhat unusual. Indeed, I struggled to find a way to get the open panel to navigate to this (I did eventually manage to do it by pressing command-shift-G and entering the path). Is there some specific reason that you end up doing that a lot?

Share and Enjoy

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

No. My earlier question wasn’t really intended as a workaround but rather as a diagnostic test. I’ve no idea what’s causing the underlying issue )-:

OK, understood.

Accessing the data volume directly in this way is somewhat unusual.

Absolutely, and it's something I'd usually not do. However, as mentioned earlier:

As some background: I've not randomly tried to break things, but got a report from a user of my app describing this issue. Apparently, migration assistant created a new folder /System/Volumes/Data/Data/ when moving to Monterey where all the files reside which he tries to edit using my app.

So it's a real-life problem, the user who reported this issue loaded the files via drag and drop.

In my tests I've dropped the files from a Finder window I've opened via Terminal.app open /System/Volumes/Data/Test. Dropping a folder to the location on the open panel also changes the folder. Didn't know that command-shift-G also works here :)

If you sent up a synthetic symbolic link to this directory, do you still have the problem when you navigate to it normally (that is, using /Test rather than /System/Volumes/Data/Test)?

If you’re not familiar with synthetic symbolic link, you can learn more in the synthetic.conf man page.

Share and Enjoy

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

If you sent up a synthetic symbolic link to this directory, do you still have the problem when you navigate to it normally (that is, using /Test rather than /System/Volumes/Data/Test)?

Yes, the problem persists also when using a synthetic symbolic link. NSOpenPanel.directoryURL points to /System/Volumes/Data/Test after choosing /Test.

Thanks for pointing to synthetic symbolic links. I wasn't aware of the feature and learned something new today!

Yes, the problem persists also when using a synthetic symbolic link.

OK, then that’s definitely bugworthy. Did you already file a bug about this? If so, what’s its number? If not, please do so now, then post the number here, just for the record.

Share and Enjoy

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

Many thanks for your help and guidance!

I've reported this as FB9843248.

  • Thanks for the bug!

Add a Comment

Any updates on this issue? I have the same issue