From f6d4def4e27b13fab174e948b94cd10550d3e10e Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Tue, 27 Sep 2011 18:19:06 -0500 Subject: [BUILTIN] Fix "test -x" as root on FreeBSD 8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit POSIX.1-2008 ยง4.4 "File Access Permission" sayeth: If execute permission is requested, access shall be granted if execute permission is granted to at least one user by the file permission bits or by an alternate access control mechanism; otherwise, access shall be denied. For historical reasons, POSIX unfortunately also allows access() and faccessat() to return success for X_OK if the current process is privileged, even when the above condition is not fulfilled and actual execution would fail. On the affected platforms, "test -x " as root started returning true on nonexecutable files when dash switched from its own emulation to the true faccessat in v0.5.7~54 (2010-04-02). Work around this by checking the permissions bits when mode == X_OK and geteuid() == 0 on such platforms. Unfortunately the behavior seems to vary from one kernel version to another, so we cannot just check the behavior at compile time and rely on that. A survey of some affected kernels: - NetBSD's kernel moved to the sane semantics in 1997 - OpenBSD's kernel made the same change in version 4.4, three years ago - FreeBSD 9's kernel fixes this but hasn't been released yet It seems safe to only apply the workaround on systems using the FreeBSD kernel for now, and to push for standardization on the expected access()/faccessat() semantics so we can drop the workaround altogether in a few years. To try it on other platforms, use "./configure --enable-test-workaround". Reported-by: Christoph Egger Analysis-by: Petr Salinger Signed-off-by: Jonathan Nieder Signed-off-by: Herbert Xu --- configure.ac | 31 +++++++++++++++++++++++++++++++ src/bltin/test.c | 20 ++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/configure.ac b/configure.ac index 60a2a26..8ae0dc6 100644 --- a/configure.ac +++ b/configure.ac @@ -90,6 +90,37 @@ AC_CHECK_FUNCS(bsearch faccessat getpwnam getrlimit isalpha killpg \ sigsetmask stpcpy strchrnul strsignal strtod strtoimax \ strtoumax sysconf) +dnl Check whether it's worth working around FreeBSD PR kern/125009. +dnl The traditional behavior of access/faccessat is crazy, but +dnl POSIX.1-2008 explicitly allows those functions to misbehave. +dnl +dnl Unaffected kernels: +dnl +dnl - all versions of Linux +dnl - NetBSD sys/kern/vfs_subr.c 1.64, 1997-04-23 +dnl - FreeBSD 9 (r212002), 2010-09-10 +dnl - OpenBSD sys/kern/vfs_subr.c 1.166, 2008-06-09 +dnl +dnl Also worked around in Debian's libc0.1 2.13-19 when using +dnl kFreeBSD 8. + +AC_ARG_ENABLE(test-workaround, AS_HELP_STRING(--enable-test-workaround, \ + [Guard against faccessat(2) that tells root all files are executable]),, + [enable_test_workaround=auto]) + +if test "enable_test_workaround" = "auto" && + test "$ac_cv_func_faccessat" = yes; then + case `uname -s 2>/dev/null` in + GNU/kFreeBSD | \ + FreeBSD) + enable_test_workaround=yes + esac +fi +if test "$enable_test_workaround" = "yes"; then + AC_DEFINE([HAVE_TRADITIONAL_FACCESSAT], [1], + [Define if your faccessat tells root all files are executable]) +fi + if test "$enable_fnmatch" = yes; then use_fnmatch= AC_CHECK_FUNCS(fnmatch, use_fnmatch=yes) diff --git a/src/bltin/test.c b/src/bltin/test.c index 458e9f5..bab9a1f 100644 --- a/src/bltin/test.c +++ b/src/bltin/test.c @@ -155,6 +155,14 @@ static int test_st_mode(const struct stat64 *, int); static int bash_group_member(gid_t); #endif +#ifdef HAVE_FACCESSAT +# ifdef HAVE_TRADITIONAL_FACCESSAT +static inline int faccessat_confused_about_superuser(void) { return 1; } +# else +static inline int faccessat_confused_about_superuser(void) { return 0; } +# endif +#endif + static inline intmax_t getn(const char *s) { return atomax10(s); @@ -493,8 +501,20 @@ equalf (const char *f1, const char *f2) } #ifdef HAVE_FACCESSAT +static int has_exec_bit_set(const char *path) +{ + struct stat64 st; + + if (stat64(path, &st)) + return 0; + return st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH); +} + static int test_file_access(const char *path, int mode) { + if (faccessat_confused_about_superuser() && + mode == X_OK && geteuid() == 0 && !has_exec_bit_set(path)) + return 0; return !faccessat(AT_FDCWD, path, mode, AT_EACCESS); } #else /* HAVE_FACCESSAT */ -- cgit 1.4.1 6627d4e017f39&follow=1'>Add type and ulimit shell keywordsJune McEnroe 2019-02-27Fix make target pattern whitespace in hiJune McEnroe 2019-02-27Delete extraneous <pre> in html.shJune McEnroe 2019-02-24Use setopt in upJune McEnroe 2019-02-24Add setoptJune McEnroe 2019-02-20Match make targets as TagJune McEnroe 2019-02-20Use $PWD in html.sh to pass absolute path to manJune McEnroe 2019-02-20Factor out html.sh and produce html for all sourcesJune McEnroe 2019-02-20Add Dirk Gently's Holistic Detective AgencyJune McEnroe 2019-02-20Move /opt/pkg after /usr in PATHJune McEnroe 2019-02-20Set man_hard_wrap in nvimJune McEnroe 2019-02-18Use hi -o anchor in upJune McEnroe 2019-02-18Don't match nested parentheses in Tag for CJune McEnroe 2019-02-18Match whitespace between * [] {}June McEnroe 2019-02-18Fix function-like #define regexJune McEnroe 2019-02-18Match Tag in RustJune McEnroe 2019-02-18Match sh functions as TagJune McEnroe 2019-02-18Match Sh and Ss as Tag in mdocJune McEnroe 2019-02-18Match statics and typedefs as TagJune McEnroe 2019-02-18Clean up htmlHeaderJune McEnroe 2019-02-18Remove hi line numberingJune McEnroe 2019-02-18Add Tag class to hiJune McEnroe 2019-02-17Generate HTML with hi -n -f html -o anchorJune McEnroe 2019-02-17Add hi -f html -o anchor for line number linksJune McEnroe 2019-02-17Simplify temp trap in upJune McEnroe 2019-02-17Add line numbers to hiJune McEnroe 2019-02-17Always split spans after newlinesJune McEnroe 2019-02-15Color format specifiers light cyan in vimJune McEnroe 2019-02-15Highlight Interp as yellowJune McEnroe 2019-02-15Highlight strings in sh command substitutionsJune McEnroe 2019-02-15Add nmap gpJune McEnroe 2019-02-14Avoid newline when copying URL to pasteboardJune McEnroe 2019-02-13Add forgotten "sixth" book of H2G2June McEnroe