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;
}

Reply via email to