[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: avoid mkdir/selinux failure when mknod is a shell built-in

From: Eric Blake
Subject: Re: avoid mkdir/selinux failure when mknod is a shell built-in
Date: Wed, 16 Apr 2008 18:04:23 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Ralf Wildenhues <Ralf.Wildenhues <at> gmx.de> writes:

> > case bug in the shell portability section.  POSIX states that exec is
> > supposed to bypass shell builtins (and while special shell builtins, like
> > 'exit', give undefined behavior when passed to exec, regular shell
> > builtins, like 'fg', are required to exist in PATH even if they can't
> > quite do as much work as their builtin counterpart).
> Can you please point me to where POSIX specifies these things?  I cannot
> find in the page describing exec, that it has to bypass built-ins.

Point taken.

XCU Command Search and Execution gives this order:

1. special built-ins
2. user-provided shell functions
3. certain utilities (for example, true or command) (the point of this list is 
to guarantee that regardless of how badly PATH is munged, these utilities will 
still work rather than executing a trojan implementation earlier on the path; 
useful since command can then be used to generate a repaired PATH)
4. PATH search, including shell-provided functions and regular builtins:

"the command shall be searched for using the PATH environment
variable as described in XBD Chapter 8 (on page 173):
i. If the search is successful:
a. If the system has implemented the utility as a regular built-in or as a
shell function, it shall be invoked at this point in the path search."

This makes it sound like the shell cannot use the builtin unless the PATH 
search succeeds, but once successful, the shell can then invoke its builtin 
instead of calling execv() on what was found on PATH.  So I guess POSIX does 
not require that exec must bypass builtins, and therefore, pdksh is not buggy, 
just different.

> Also, I cannot find at all that regular shell builtins have to exist as
> independent programs in $PATH.  The only thing I found wrt. special
> built-ins was
>    The special built-in utilities in this section need not be provided
>    in a manner accessible via the exec family of functions defined in
>    the System Interfaces volume of IEEE Std 1003.1-2001.
> which isn't a requirement on the implementation.

In addition to the above wording about simple command execution requiring a 
successful path search, I think this wording in command is most applicable here:

"Two types of regular built-ins could be encountered on a system and these are 
described separately by command. The description of command search in Command 
Search and Execution allows for a standard utility to be implemented as a 
regular built-in as long as it is found in the appropriate place in a PATH 
search. So, for example, command -v true might yield /bin/true or some similar 
pathname. Other implementation-defined utilities that are not defined by this 
volume of IEEE Std 1003.1-2001 might exist only as built-ins and have no 
pathname associated with them. These produce output identified as (regular) 
built-ins. Applications encountering these are not able to count on execing 
them, using them with nohup, overriding them with a different PATH , and so on."

So mknod qualifies as a candidate for a regular builtin that need not be PATH-
based (since POSIX doesn't require mknod(1)).  I would almost claim that true 
MUST exist in the PATH, except that true is on the list of 17 utilities that 
must work regardless of PATH search (hmm - the Posix example of command -v true 
yielding /bin/true is thus suspect).  But printf is a good example - it is a 
POSIX-mandated utility, not on the special list of required utilities, but 
often implemented as a builtin; even if it is a builtin, this statement says it 
must also exist on PATH.

> I'm looking at SUSv3, by the way.

As am I.

> * Eric Blake wrote on Wed, Apr 16, 2008 at 06:14:35PM CEST:
> > 
> > Any comments before I check it in?

Thanks for the nitpicks.  How about this attempt at rewording things? (I 
dropped mention of exec special-builtin, since that is already explicitly 
undefined by Posix)

>From 9651f4a0e1b80c55da23a5ceaa0237121e0b95f2 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Wed, 16 Apr 2008 10:10:31 -0600
Subject: [PATCH] Document pdksh exec behavior.

* doc/autoconf.texi (Limitations of Builtins) <exec>: New
Discovered by Jim Meyering.

Signed-off-by: Eric Blake <address@hidden>
 ChangeLog         |    7 +++++++
 doc/autoconf.texi |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b1d9a4e..9d9d04e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-04-16  Eric Blake  <address@hidden>
+       Document pdksh exec behavior.
+       * doc/autoconf.texi (Limitations of Builtins) <exec>: New
+       subsection.
+       Discovered by Jim Meyering.
 2008-04-14  Ralf Wildenhues  <address@hidden>
        * tests/autotest.at (AT_CHECK_AT): Allow to pass additional
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 8b10387..554d2ec 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -13945,6 +13945,54 @@ but portable scripts should not rely on this.
 You should not rely on @code{LINENO} within @command{eval}.
 @xref{Special Shell Variables}.
address@hidden @command{exec}
address@hidden -----------------
address@hidden @command{exec}
+Posix describes several categories of shell built-ins.  Special
+built-ins (such as @command{exit}) must impact the environment of the
+current shell, and need not be available through @command{exec}.  All
+other built-ins are regular, and must not propagate variable assignments
+to the environment of the current shell.  However, the group of regular
+built-ins is further distinguished by commands that do not require a
address@hidden search (such as @command{cd}), in contrast to built-ins that
+are offered as a more efficient version of something that must still be
+found in a @env{PATH} search (such as @command{echo}).  Posix is not
+clear on whether @command{exec} must work with the list of 17 utilities
+that are invoked without a @env{PATH} search, and many platforms lack an
+executable for some of those built-ins:
+$ @kbd{sh -c 'exec cd /tmp'}
+sh: line 0: exec: cd: not found
address@hidden example
+All other built-ins that provide utilities specified by Posix must have
+a counterpart executable that exists on @env{PATH}, although Posix
+allows @command{exec} to use the built-in instead of the executable.
+For example, contrast @command{bash} 3.2 and @command{pdksh} 5.2.14:
+$ @kbd{bash -c 'pwd --version' | head -n1}
+bash: line 0: pwd: --: invalid option
+pwd: usage: pwd [-LP]
+$ @kbd{bash -c 'exec pwd --version' | head -n1}
+pwd (GNU coreutils) 6.10
+$ @kbd{pdksh -c 'exec pwd --version' | head -n1}
+pdksh: pwd: --: unknown option
address@hidden example
+When it is desired to avoid a regular shell built-in, the workaround is
+to use some other forwarding command, such as @command{env} or
address@hidden, that will ensure a path search:
+$ @kbd{pdksh -c 'exec true --version' | head -n1}
+$ @kbd{pdksh -c 'nice true --version' | head -n1}
+true (GNU coreutils) 6.10
+$ @kbd{pdksh -c 'env true --version' | head -n1}
+true (GNU coreutils) 6.10
address@hidden example
 @item @command{exit}
 @c -----------------
 @prindex @command{exit}

Bug-coreutils mailing list

reply via email to

[Prev in Thread] Current Thread [Next in Thread]