[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