klibc-bot for Jonathan Nieder
2020-Mar-28 21:48 UTC
[klibc] [klibc:update-dash] dash: [BUILTIN] Fix "test -x" as root on FreeBSD 8
Commit-ID: 8f7f6479f4dc1c65f9574eb0596d50bae13b9ba9 Gitweb: http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=8f7f6479f4dc1c65f9574eb0596d50bae13b9ba9 Author: Jonathan Nieder <jrnieder at gmail.com> AuthorDate: Tue, 27 Sep 2011 18:19:06 -0500 Committer: Ben Hutchings <ben at decadent.org.uk> CommitDate: Sat, 28 Mar 2020 21:42:54 +0000 [klibc] dash: [BUILTIN] Fix "test -x" as root on FreeBSD 8 [ dash commit f6d4def4e27b13fab174e948b94cd10550d3e10e ] 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 <path>" 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 <christoph at debian.org> Analysis-by: Petr Salinger <Petr.Salinger at seznam.cz> Signed-off-by: Jonathan Nieder <jrnieder at gmail.com> Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au> Signed-off-by: Ben Hutchings <ben at decadent.org.uk> --- usr/dash/bltin/test.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/usr/dash/bltin/test.c b/usr/dash/bltin/test.c index 458e9f55..bab9a1f9 100644 --- a/usr/dash/bltin/test.c +++ b/usr/dash/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 */
Apparently Analagous Threads
- [klibc:update-dash] [BUILTIN] Fix "test -x" as root on FreeBSD 8
- [klibc:update-dash] dash: builtin: Use test_access from NetBSD when faccessat is unavailable
- [klibc:update-dash] [BUILTIN] Use PRIdMAX instead of %j in printf
- [klibc:update-dash] dash: [BUILTIN] Use PRIdMAX instead of %j in printf
- [klibc:update-dash] [BUILTIN] Fixed argument parsing crash in test