There is one particular case when open_tree is more powerful than openat with O_PATH. open_tree supports AT_EMPTY_PATH, and openat supports nothing similar. This means that we can convert normal O_RDONLY file descriptor to O_PATH descriptor using open_tree! I. e.: rd = openat(AT_FDCWD, "/tmp/a", O_RDONLY, 0); // Regular file open_tree(rd, "", AT_EMPTY_PATH); You can achieve same effect using /proc: rd = openat(AT_FDCWD, "/tmp/a", O_RDONLY, 0); // Regular file snprintf(buf, sizeof(buf), "/proc/self/fd/%d", rd); openat(AT_FDCWD, buf, O_PATH, 0); But still I think this has security implications. This means that even if we deny access to /proc for container, it still is able to convert O_RDONLY descriptors to O_PATH descriptors using open_tree. I. e. this is yet another thing to think about when creating sandboxes. I know you delivered a talk about similar things a lot of time ago: https://lwn.net/Articles/934460/ . (I tested this.) -- Askar Safin https://types.pl/@safinaskar