Index | Thread | Search

From:
"H. Hartzer" <h@hartzer.sh>
Subject:
Re: openat(2) is mostly useless, sadly
To:
"Theo de Raadt" <deraadt@openbsd.org>, <tech@openbsd.org>
Date:
Sun, 01 Jun 2025 16:55:46 +0000

Download raw body.

Thread
  • H. Hartzer:

    openat(2) is mostly useless, sadly

  • H. Hartzer:

    openat(2) is mostly useless, sadly

  • 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 <fcntl.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/stat.h>
    
    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;
    }
    
    
  • H. Hartzer:

    openat(2) is mostly useless, sadly

  • H. Hartzer:

    openat(2) is mostly useless, sadly