commit: 4d33585e8070f17c182888f3573e5ce3d1ff6a70 Author: Mike Gilbert <floppym <AT> gentoo <DOT> org> AuthorDate: Mon Jul 17 15:03:13 2023 +0000 Commit: Mike Gilbert <floppym <AT> gentoo <DOT> org> CommitDate: Fri Aug 4 00:26:30 2023 +0000 URL: https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=4d33585e
libsbutil: add sbio_faccessat and use it in sb_exists sbio_faccessat allows libsbutil to access the unwrapped version of faccessat when called from libsandbox. Using faccessat in place of fstatat seems to give a small boost in performance. Pass AT_EACCESS faccessat to enable a faster path if uid != euid. Bug: https://bugs.gentoo.org/910273 Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org> (cherry picked from commit 0317bbe09fe23e4bd972ee254f14817def701731) libsandbox/libsandbox.c | 1 + libsandbox/wrappers.h | 2 ++ libsbutil/sb_exists.c | 10 ++++++++++ libsbutil/sbutil.h | 1 + src/sandbox.c | 1 + 5 files changed, 15 insertions(+) diff --git a/libsandbox/libsandbox.c b/libsandbox/libsandbox.c index 08b85ce..4edcf60 100644 --- a/libsandbox/libsandbox.c +++ b/libsandbox/libsandbox.c @@ -54,6 +54,7 @@ static char message_path[SB_PATH_MAX]; bool sandbox_on = true; static bool sb_init = false; static bool sb_env_init = false; +int (*sbio_faccessat)(int, const char *, int, int) = sb_unwrapped_faccessat; int (*sbio_open)(const char *, int, mode_t) = sb_unwrapped_open; FILE *(*sbio_popen)(const char *, const char *) = sb_unwrapped_popen; diff --git a/libsandbox/wrappers.h b/libsandbox/wrappers.h index bf5bf64..3237397 100644 --- a/libsandbox/wrappers.h +++ b/libsandbox/wrappers.h @@ -15,6 +15,8 @@ */ #define sb_unwrapped_access sb_unwrapped_access_DEFAULT attribute_hidden int sb_unwrapped_access (const char *, int); +#define sb_unwrapped_faccessat sb_unwrapped_faccessat_DEFAULT +attribute_hidden int sb_unwrapped_faccessat (int, const char *, int, int); #define sb_unwrapped_getcwd sb_unwrapped_getcwd_DEFAULT attribute_hidden char *sb_unwrapped_getcwd (char *, size_t); #define sb_unwrapped_open sb_unwrapped_open_DEFAULT diff --git a/libsbutil/sb_exists.c b/libsbutil/sb_exists.c index d34f0cc..c2171fe 100644 --- a/libsbutil/sb_exists.c +++ b/libsbutil/sb_exists.c @@ -10,5 +10,15 @@ int sb_exists(int dirfd, const char *pathname, int flags) { struct stat64 buf; + + if (sbio_faccessat(dirfd, pathname, F_OK, flags|AT_EACCESS) == 0) + return 0; + + /* musl's faccessat gives EINVAL when the kernel does not support + * faccessat2 and AT_SYMLINK_NOFOLLOW is set. + * https://www.openwall.com/lists/musl/2023/06/19/1 */ + if (errno != EINVAL) + return -1; + return fstatat64(dirfd, pathname, &buf, flags); } diff --git a/libsbutil/sbutil.h b/libsbutil/sbutil.h index 981fe0d..ed335e2 100644 --- a/libsbutil/sbutil.h +++ b/libsbutil/sbutil.h @@ -98,6 +98,7 @@ extern const char sb_fd_dir[]; const char *sb_get_cmdline(pid_t pid); /* libsandbox need to use a wrapper for open */ +attribute_hidden extern int (*sbio_faccessat)(int, const char *, int, int); attribute_hidden extern int (*sbio_open)(const char *, int, mode_t); attribute_hidden extern FILE *(*sbio_popen)(const char *, const char *); extern const char *sbio_message_path; diff --git a/src/sandbox.c b/src/sandbox.c index ed0c7f6..f4ffd20 100644 --- a/src/sandbox.c +++ b/src/sandbox.c @@ -21,6 +21,7 @@ static int print_debug = 0; #define dprintf(fmt, args...) do { if (print_debug) printf(fmt, ## args); } while (0) #define dputs(str) do { if (print_debug) puts(str); } while (0) +int (*sbio_faccessat)(int, const char *, int, int) = faccessat; int (*sbio_open)(const char *, int, mode_t) = (void *)open; FILE *(*sbio_popen)(const char *, const char *) = popen;