Oğuz On Tue, Oct 24, 2023 at 1:53 PM Jonathan Wakely <jwak...@redhat.com> wrote: > > > > On Tue, 24 Oct 2023 at 07:10, Oğuz via austin-group-l at The Open Group > <austin-group-l@opengroup.org> wrote: >> >> On Tuesday, October 24, 2023, enh via austin-group-l at The Open Group >> <austin-group-l@opengroup.org> wrote: >>> >>> netbsd checks that _PATH_BSHELL is exectuable with access(2) >>> (but doesn't actually _execute_ anything). apple's copy of freebsd has >>> a local change similar to the netbsd one. glibc seems to actually try >>> to _run_ a shell: >>> ``` >>> [pid 3612818] execve("/bin/sh", ["sh", "-c", "exit 0"], 0x7fff98502fe8 >>> ``` >> >> >> None of those guarantee that the shell is actually gonna work. I think they >> all should just return 1. >> >>> but a >>> POSIX system can have those kinds of features that could mean >>> system(3) doesn't actually work _for this process_ >> >> >> Such a system should provide the means for testing if a process is in that >> state, and the means shouldn't involve auditing the shell executable. > > > Why not? Checking if you can run /bin/sh seems like the most direct and > accurate way of checking if the process can run /bin/sh. POSIX might require > /bin/sh to be usable, so a "pure POSIX" system can safely just return > non-zero from system(NULL). But a system that supports features like SELinux > that aren't part of POSIX might want to do extra checks, which wouldn't be > required on a system where /bin/sh is always available. > > Why require those systems to provide some other non-standard API for testing > it when system(NULL) is specified by C to do that job?
system(NULL) is specified by both C and POSIX to return whether the host environment features a command processor or not. It's merely a feature test, as evident from the following paragraphs from POSIX Issue 8 draft 3 P2196 L71808-71821: > Note that, system(NULL) is required to return non-zero, indicating that there > is a command > language interpreter. At first glance, this would seem to conflict with the > ISO C standard which > allows system(NULL) to return zero. There is no conflict, however. A system > must have a > command language interpreter, and is non-conforming if none is present. It is > therefore > permissible for the system() function on such a system to implement the > behavior specified by > the ISO C standard as long as it is understood that the implementation does > not conform to > POSIX.1-202x if system(NULL) returns zero. > > It was explicitly decided that when command is NULL, system() should not be > required to check > to make sure that the command language interpreter actually exists with the > correct mode, that > there are enough processes to execute it, and so on. The call system(NULL) > could, theoretically, > check for such problems as too many existing child processes, and return > zero. However, it > would be inappropriate to return zero due to such a (presumably) transient > condition. If some > condition exists that is not under the control of this application and that > would cause any > system() call to fail, that system has been rendered non-conforming. On a system where certain users/processes can have limited/no shell access, providing a separate interface like do_I_have_shell_access() would be more appropriate than overloading system(NULL).