[PATCH v2 3/3] sandbox/seunshare: pin_dir: use openat2 if available

Stephen Smalley <[email protected]>
Newsgroups org.kernel.vger.selinux
Message-ID <[email protected]>
Update seunshare's pin_dir() helper to use openat2() if defined to
optimize the lookup of the directory and prevent following any
intermediate symlinks. Fall back to the existing open() on
ENOSYS/EINVAL so that pre-5.6 and seccomp-filtered environments are
unaffected.

Signed-off-by: Stephen Smalley <[email protected]>
---
 sandbox/seunshare.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c
index 3fa42f9a..f2d637e1 100644
--- a/sandbox/seunshare.c
+++ b/sandbox/seunshare.c
@@ -10,8 +10,12 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/syscall.h>
 #include <syslog.h>
 #include <sys/mount.h>
+#ifdef __NR_openat2
+#include <linux/openat2.h>
+#endif
 #include <glob.h>
 #include <pwd.h>
 #include <sched.h>
@@ -219,10 +223,19 @@ static int check_owner_gid(gid_t gid, const char *file, struct stat *st)
  */
 static int pin_dir(const char *dir, struct stat *st_out)
 {
-	int fd;
+	int fd = -1;
 	struct stat sb;
 
-	fd = open(dir, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
+#ifdef __NR_openat2
+	struct open_how how = {
+		.flags = O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC,
+		.resolve = RESOLVE_NO_SYMLINKS | RESOLVE_NO_MAGICLINKS,
+	};
+
+	fd = syscall(__NR_openat2, AT_FDCWD, dir, &how, sizeof(how));
+	if (fd < 0 && (errno == ENOSYS || errno == EINVAL))
+#endif
+		fd = open(dir, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
 	if (fd < 0) {
 		fprintf(stderr, _("Failed to open %s: %m\n"), dir);
 		return -1;
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.