diff mbox

[3/3] selftests: check O_ATROOT and AT_FDROOT flags

Message ID 1469047377-13128-4-git-send-email-avagin@openvz.org
State New, archived
Headers show

Commit Message

Andrey Vagin July 20, 2016, 8:42 p.m. UTC
These flags mean that the first argument "dirfd" of *at syscall-s set as
root for the current operation.

With these flags absolute symlinks have to be resolved relative to
dirfd.

This test create a file and an absolute symlink on it, which can be
resoled only if a proper root is set.

Signed-off-by: Andrey Vagin <avagin@openvz.org>
---
 tools/testing/selftests/Makefile                |  1 +
 tools/testing/selftests/lookup/.gitignore       |  1 +
 tools/testing/selftests/lookup/Makefile         |  8 +++
 tools/testing/selftests/lookup/lookup_at_root.c | 71 +++++++++++++++++++++++++
 tools/testing/selftests/lookup/run.sh           | 14 +++++
 5 files changed, 95 insertions(+)
 create mode 100644 tools/testing/selftests/lookup/.gitignore
 create mode 100644 tools/testing/selftests/lookup/Makefile
 create mode 100644 tools/testing/selftests/lookup/lookup_at_root.c
 create mode 100755 tools/testing/selftests/lookup/run.sh
diff mbox

Patch

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index ff9e5f2..72555c8 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -9,6 +9,7 @@  TARGETS += futex
 TARGETS += ipc
 TARGETS += kcmp
 TARGETS += lib
+TARGETS += lookup
 TARGETS += membarrier
 TARGETS += memfd
 TARGETS += memory-hotplug
diff --git a/tools/testing/selftests/lookup/.gitignore b/tools/testing/selftests/lookup/.gitignore
new file mode 100644
index 0000000..c9a963f
--- /dev/null
+++ b/tools/testing/selftests/lookup/.gitignore
@@ -0,0 +1 @@ 
+lookup_at_root
diff --git a/tools/testing/selftests/lookup/Makefile b/tools/testing/selftests/lookup/Makefile
new file mode 100644
index 0000000..042b26f
--- /dev/null
+++ b/tools/testing/selftests/lookup/Makefile
@@ -0,0 +1,8 @@ 
+TEST_PROGS := run.sh
+
+all: lookup_at_root
+
+clean:
+	$(RM) lookup_at_root
+include ../lib.mk
+
diff --git a/tools/testing/selftests/lookup/lookup_at_root.c b/tools/testing/selftests/lookup/lookup_at_root.c
new file mode 100644
index 0000000..6723dc8
--- /dev/null
+++ b/tools/testing/selftests/lookup/lookup_at_root.c
@@ -0,0 +1,71 @@ 
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/prctl.h>
+#include <linux/limits.h>
+
+#define pr_err(fmt, ...) \
+		({ \
+			fprintf(stderr, "%s:%d:" fmt ": %m\n", \
+				__func__, __LINE__, ##__VA_ARGS__); \
+			1; \
+		})
+
+#ifndef O_ATROOT
+#define O_ATROOT       040000000        /* dfd is a root */
+#endif
+#ifndef AT_FDROOT
+#define AT_FDROOT      0x2000		/* Resolve a path as if dirfd is root */
+#endif
+
+int main(int argc, char **argv)
+{
+	struct stat st;
+	int fd, dfd;
+	char path[PATH_MAX];
+
+	dfd = open(argv[1], O_RDONLY);
+	if (dfd < 0)
+		return pr_err("open");
+
+	snprintf(path, sizeof(path), "%s/test", argv[1]);
+	if (mkdir(path, 755))
+		return pr_err("mkdir");
+
+	if (symlinkat("/test", dfd, "./test.link"))
+		return pr_err("symlinkat");
+
+	fd = openat(dfd, "test.link", O_RDONLY | O_ATROOT);
+	if (fd < 0)
+		return pr_err("open");
+
+	if (fchdir(dfd))
+		return pr_err("fchdir");
+
+	fd = openat(AT_FDCWD, "test.link", O_RDONLY | O_ATROOT);
+	if (fd < 0)
+		return pr_err("open");
+	close(fd);
+
+	fd = openat(AT_FDCWD, "/test.link", O_RDONLY | O_ATROOT);
+	if (fd < 0)
+		return pr_err("open");
+	close(fd);
+
+	if (fstatat(AT_FDCWD, "test.link", &st, AT_FDROOT))
+		return pr_err("fstatat");
+	if (fstatat(dfd, "test.link", &st, AT_FDROOT))
+		return pr_err("fstatat");
+	if (mknodat(dfd, "./test/test.file", 0644 | S_IFREG, 0))
+		return pr_err("mknod");
+	if (linkat(dfd, "./test.link/test.file",
+			dfd, "./test.link/test.file.link", AT_FDROOT))
+		return pr_err("linkat");
+	if (unlinkat(dfd, "./test.link/test.file.link", AT_FDROOT))
+		return pr_err("unlinkat");
+
+	return 0;
+}
diff --git a/tools/testing/selftests/lookup/run.sh b/tools/testing/selftests/lookup/run.sh
new file mode 100755
index 0000000..86cc51b
--- /dev/null
+++ b/tools/testing/selftests/lookup/run.sh
@@ -0,0 +1,14 @@ 
+#!/bin/sh
+
+set -e
+
+test_dir=`mktemp -d /tmp/lookup_test.XXXXXX`
+mount -t tmpfs lookup_at_root $test_dir
+
+ret=0
+./lookup_at_root $test_dir || ret=$?
+
+umount $test_dir
+rmdir $test_dir
+
+exit $ret