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 --- src/bltin/test.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src') 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 9:58 -0400'>2018-08-21Clean up MakefileJune McEnroe 2018-08-05Fix color pairs once and for all v1June McEnroe 2018-08-05Add chat to index.htmlJune McEnroe 2018-07-25Set client sockets SNDBUF to twice tile sizeJune McEnroe 2018-07-24Revert "Do not set non-blocking on client sockets"June McEnroe 2018-07-24Print time_t with %jd in metaJune McEnroe 2018-07-24Do not set non-blocking on client socketsJune McEnroe 2018-07-24Use EV_SETJune McEnroe 2018-07-24Link with -lcursesJune McEnroe 2018-07-23Fix NaNs in serverMapJune McEnroe 2018-07-22Add libm.so to chroot.tarJune McEnroe 2018-07-22Link with -lmJune McEnroe 2018-07-22Add map to clientJune McEnroe 2018-07-21Refactor readInput for each modeJune McEnroe 2018-07-19Add ARRAY_LEN macroJune McEnroe 2018-07-17Add server map generationJune McEnroe 2018-07-17Tabify sourceJune McEnroe 2018-05-13Fix ncurses color pair numberingJune McEnroe 2018-04-09Use anonymous unionJune McEnroe 2018-04-09Replace #define with enum or const where possibleJune McEnroe 2018-03-31Link against ncursesJune McEnroe 2018-03-05Miscellaneous code cleanupJune McEnroe 2018-03-05Pass message structs by valueJune McEnroe 2018-03-05Use stdio in merge and metaJune McEnroe 2018-03-05Clean up spawn constantsJune McEnroe 2018-03-05Rename Tile timestamps {create,modify,access}TimeJune McEnroe 2018-03-05Pack message type enumsJune McEnroe 2018-03-05Undef COLOR_ constants in torus.hJune McEnroe 2018-03-05Generate tagsJune McEnroe 2017-10-03Simplify Makefile with pattern ruleJune McEnroe 2017-09-27Remove leading blank linesJune McEnroe 2017-09-27Add merge.c to READMEJune McEnroe 2017-09-03Assert client coords are valid after movementJune McEnroe 2017-09-03Relicense AGPLJune McEnroe 2017-09-01Revert "Add client readOnly mode"June McEnroe 2017-09-01Remove clientRemove call from clientCastJune McEnroe 2017-09-01Add client readOnly modeJune McEnroe 2017-08-31Clean up merge toolJune McEnroe 2017-08-31Choose B for tiles with equal modify timesJune McEnroe 2017-08-31Add quick data file merge toolJune McEnroe 2017-08-30Use only foreground color for selecting spawnJune McEnroe 2017-08-29Add four additional spawnsJune McEnroe 2017-08-28Add respawningJune McEnroe 2017-08-26Move license above includesJune McEnroe 2017-08-26Snapshot metadataJune McEnroe 2017-08-26Add meta.c to READMEJune McEnroe 2017-08-26Use MakefileJune McEnroe