From: "H. Hartzer" Subject: Re: openat(2) is mostly useless, sadly To: "Theo de Raadt" , Date: Sun, 01 Jun 2025 16:55:46 +0000 I wrote a small test program for this. I only ran it as root, so maybe that changes something, but I could not get the chroot-like functionality to work. I'm able to chdir right back out. -Henrich #include #include #include #include char buffer[1024]; int main() { mkdir("o-below-test-dir", 0755); int underfd = open("o-below-test-dir/under.txt", O_CREAT | O_WRONLY); write(underfd, "This is under.txt\n", 19); close(underfd); mkdir("o-below-test-dir/below_dir", 0755); int dirfd = open("o-below-test-dir/below_dir", O_DIRECTORY); if (dirfd < 0) { fprintf(stderr, "Unable to open directory.\n"); return 1; } // Validate normal behavior. int filefd = openat(dirfd, "../under.txt", O_RDONLY); if (filefd < 0) { fprintf(stderr, "Unable to open file.\n"); return 1; } int byte_count = read(filefd, &buffer, sizeof(buffer)); fprintf(stderr, "Read %d bytes.\n", byte_count); printf("%s\n", buffer); fcntl(dirfd, F_BELOW); // Now we're F_BELOW, verify. if (openat(dirfd, "../under.txt", O_RDONLY) > 0) { fprintf(stderr, "Should not be able to open file.\n"); return 1; } if (unlinkat(dirfd, "../under.txt", 0) > 0) { fprintf(stderr, "Should not be able to unlink file.\n"); return 1; } // chroot-like doesn't seem to work? I may be misunderstanding this. fchdir(dirfd); chdir("../.."); // Cleanup. if (unlink("o-below-test-dir/under.txt") < 0) { fprintf(stderr, "Was unable to cleanup o-below-test-dir/under.txt.\n"); return 1; } if (rmdir("o-below-test-dir/below_dir") < 0) { fprintf(stderr, "Was unable to cleanup o-below-test-dir/below_dir.\n"); return 1; } if (rmdir("o-below-test-dir") < 0) { fprintf(stderr, "Was unable to cleanup o-below-test-dir.\n"); return 1; } fprintf(stderr, "Success!\n"); return 0; }