In my application, I am trying to check if a path is inside of a specific directory. E.g., I want the files in the path /x/y/z
not to be accessible by parts of my application. I cannot use traditional file permissions, as other parts of the application should be able to access these files.
Several Internet resources suggest the use of realpath
to first canonicalize paths, i.e., resolving all symlinks and instances of ..
(e.g. 1, 2).
However, it seems not to be possible to perform path resolution followed by an open
without an race condition (TOCTOU).
char *resolved = realpath("/my/potentially/dangerous/path.txt", NULL);
// someone changes any part of the path to a symlink to something else <--- race condition
if (check_path(resolved)) {
// <--- race condition
int fd = open(resolved, O_RDONLY);
}
Am I overlooking something or does POSIX (and Linux) not provide any way to do something like this without a race condition?
What about 'openat2' (Linux only)?
And once you have a file descriptor, see man open