Hi! Jonathan Nieder <[email protected]> writes: > Hi Christoph, > > Christoph Egger wrote: > >> dash relies, for it's test builtin that faccessat returns useable >> values for X_OK when called from the root user. Unfortunately that's not >> true on kfreebsd (and seemingly not required by POSIX, see >> #640325). > > Thanks for reporting it. The rationale to the description of access() > in POSIX says: > > Historical implementations of access() do not test file access > correctly when the process real user ID is superuser. In > particular, they always return zero when testing execute > permissions with regard to whether the file is executable. > [...] > New implementations are discouraged from returning X_OK unless > at least one execution permission bit is set. > > In other words, this weird part of POSIX is meant as a historical > exception, not a good behavior. > > In glibc-bsd, I think it was just an oversight --- access() > implemented the expected X_OK semantics already, as did faccessat() > when used with a sufficiently old kernel. Petr fixed faccessat() > in the development repository just now.
Jep I noticed (and am glad it is done there -- that kind of behaviour is quite strange). Note it wasn't my original intention to fill this as a dash bug right now, however that bounce from sending to [email protected] didn't leave me a chance to get dash people informed ;) -- and this little problem is currently blocking the openjdk builds that might now work on kfreebsd which woulkd be a awesome step forward :-). > All that said, for the sake of smooth upgrades and to support the > aforementioned historical implementations (do they exist for > faccessat?), dash should probably use a workaround. How about this? > > Signed-off-by: Jonathan Nieder <[email protected]> > --- > src/bltin/test.c | 11 +++++++++++ > 1 files changed, 11 insertions(+), 0 deletions(-) > > diff --git a/src/bltin/test.c b/src/bltin/test.c > index 90135e14..1093b59f 100644 > --- a/src/bltin/test.c > +++ b/src/bltin/test.c > @@ -485,8 +485,19 @@ 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 (mode == X_OK && geteuid() == 0 && !has_exec_bit_set(path)) > + return 0; > return !faccessat(AT_FDCWD, path, mode, AT_EACCESS); > } > #else /* HAVE_FACCESSAT */ Jep that works fine here. Regards Christoph -- 9FED 5C6C E206 B70A 5857 70CA 9655 22B9 D49A E731 Debian Developer | Lisp Hacker | CaCert Assurer -- To UNSUBSCRIBE, email to [email protected] with a subject of "unsubscribe". Trouble? Contact [email protected]

