[PATCH v2 1/3] libselinux: selinux_restorecon: use openat2 if defined

Stephen Smalley <[email protected]>
Newsgroups org.kernel.vger.selinux
Message-ID <[email protected]>
Update selinux_restorecon()'s safe_open() helper to use openat2()
if defined to optimize the lookup of the initial pathname. Fall
back to the existing per-component lookup on ENOSYS/EINVAL so
that pre-5.6 and seccomp-filtered environments are unaffected.

Signed-off-by: Stephen Smalley <[email protected]>
---
 libselinux/src/selinux_restorecon.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/libselinux/src/selinux_restorecon.c b/libselinux/src/selinux_restorecon.c
index b34d8e60..30f1b836 100644
--- a/libselinux/src/selinux_restorecon.c
+++ b/libselinux/src/selinux_restorecon.c
@@ -25,7 +25,11 @@
 #include <sys/vfs.h>
 #include <sys/statvfs.h>
 #include <sys/utsname.h>
+#include <sys/syscall.h>
 #include <linux/magic.h>
+#ifdef __NR_openat2
+#include <linux/openat2.h>
+#endif
 #include <libgen.h>
 #include <syslog.h>
 #include <assert.h>
@@ -1114,6 +1118,25 @@ static int safe_open(const char *path, struct stat *sb)
 		return -1;
 	}
 
+#ifdef __NR_openat2
+	struct open_how how = {
+		.flags = O_PATH | O_NOFOLLOW | O_CLOEXEC,
+		.resolve = RESOLVE_NO_SYMLINKS | RESOLVE_NO_MAGICLINKS,
+	};
+
+	nfd = syscall(__NR_openat2, AT_FDCWD, path, &how, sizeof(how));
+	if (nfd >= 0) {
+		if (fstat(nfd, sb) < 0) {
+			close(nfd);
+			return -1;
+		}
+		return nfd;
+	}
+
+	if (errno != ENOSYS && errno != EINVAL)
+		return -1;
+#endif
+
 	copy = strdup(path);
 	if (!copy)
 		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.