Today I finally got to try unveil(2) and retrofit it into one of my applications. I really like it.
But there was one thing that tripped me up for a bit. When trying to move a file from one directory into a subdirectory I kept getting an ENOENT when trying to accomplish this with renameat(2). Attached is a little sample program that shows the behavior. You can see the problem when trying to move the source file from the current dir into the test dir: $ cc unveilrenameat.c && ./a.out . unveilrenameat.c test a.out: moving ./unveilrenameat.c to test/unveilrenameat.c a.out: renameat: No such file or directory Instead I would have expected it to have moved the source file into the test directory, this is what it does when using rename(2) instead. Besides this nitpick, thanks for unveil! -Tim
#include <sys/stat.h> #include <err.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char **argv) { const char *basedir, *file, *subdir; int fd1, fd2; if (argc != 4) errx(1, "usage: %s basedir file subdir", getprogname()); basedir = argv[1]; file = argv[2]; subdir = argv[3]; warnx("moving %s/%s to %s/%s", basedir, file, subdir, file); if (unveil(basedir, "rwc") == -1) err(1, "unveil"); if (unveil(NULL, NULL) == -1) err(1, "unveil"); if ((fd1 = open(basedir, O_RDONLY)) == -1) err(1, "open"); if (mkdirat(fd1, subdir, 0755) == -1 && errno != EEXIST) err(1, "mkdirat"); if ((fd2 = openat(fd1, subdir, O_DIRECTORY|O_RDONLY)) == -1) err(1, "openat"); if (renameat(fd1, file, fd2, file) == -1) err(1, "renameat"); return 0; }