Hello all,
I'm looking for clarification on the functionality of Full Disk Access (FDA) in macOS. To illustrate my case, consider the following simple example program:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main(void)
{
const char *filePath = "/Library/Preferences/com.apple.TimeMachine.plist";
// Try to open the file
FILE *file = fopen(filePath, "r");
if (file == NULL) {
// If there is an error opening the file, print the error and exit
printf("Error opening file %s: %s\n", filePath, strerror(errno));
return 1;
}
fclose(file);
// If we reached here, the file was successfully opened
printf("File %s opened successfully\n", filePath);
return 0;
}
When this program is built and executed in Terminal.app with Terminal having FDA, the file opens successfully. Conversely, when FDA is revoked from Terminal and granted to the program, an error occurs due to insufficient privileges.
Interestingly, building and executing the program within Xcode, without Xcode having FDA, but granting FDA to the resulting binary (either debug or release), allows the file to open successfully. Which is what I would expect for the above case as well.
Running the same binary (with FDA enabled), which runs successfully within Xcode, in Terminal yields an error message.
So, I have the following questions based on these observations:
- Why does the program access the file successfully when run from within Xcode, despite Xcode lacking FDA?
- Why does the program fail to access the file when run from Terminal without FDA, even though the program itself has FDA?
- What is the precise relationship between a parent process and its child process concerning FDA?
These tests were conducted on macOS 14.5 with Xcode 15.4.
Thanks in advance!
TCC has a the concept of finding the responsible code. I talk about this in some detail in On File System Permissions. The exact algorithm it uses for this is not documented, has changed in the past, and may well change in the future. Given that, I’m not able to answer your specific questions [1].
If your building a product for macOS then I’m happy to offer suggestions for how to structure it to work well with TCC, but now and in the future. If you’d like to go down that path, please post some details about what your product does.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] Well I could answer “These are all implementation details of the current algorithm.” but that’s not very helpful (-: