Sumanth Naropanth wrote:
[CC:'ing shell-discuss at opensolaris.org to get some feedback from the
experts there] 
> Here is a proposal for a small project that aims to deliver a secure C
> library function as an alternative to the system(3C) function. Please
> share your thoughts and comments.
> 
> Regards,
> Sumanth
> 
> ----------------------------------------------------------------------
> Proposal:
> 
> The system(3C) C library function invokes the shell to execute the
> argument string supplied to it. This function is frequently used to
> execute a file when it is not necessary to invoke the shell at all.
> Searching through the OpenSolaris source files for the usage of the
> system() function produces over 200 hits, a large number of which are
> just binary executions which should rather be done in a safer way using
> the exec(2) family of system calls.
> 
> The system(3C) function subjects the execution of the file/command to be
> affected by the PATH, IFS and other environmental variables. Special
> characters may be intentionally injected in cases where system() is
> called on unsanitized user input, causing system() to execute arbitrary
> commands. The Sun Bugtraq database lists several security bugs that
> can be root-caused to poor usage of the system(3C) function. Developers
> usually prefer to use the system() function over
> fork()/exec()/wait() due to its simple semantics.
> 
> This project aims to provide a new public interface called the
> 'exec_system()'. This function will be implemented to provide the same
> ease of use as the system(3C), by defining a single (const char *)
> argument. The implementation will be a wrapper around the
> posix_spawn(3C)/waitpid(3C) functions. This interface will provide
> greater security in comparison with the system() function by avoiding
> shell invocation. Quoted arguments will be supported by using a new
> macro called 'ES_QUOTE', which will be defined as:
> 
>           #define ES_QUOTE      '\377%s\377'
> 
> The special character '\377' is chosen since it lies outside the
> printable character set. This quoting mechanism will make it harder for
> arbitrarily quoted user inputs to cause execution of unintended code.

It makes it harder but AFAIK it won't prevent it, right ? If it can't be
prevented - where is the advantage over |system()| ? Remeber that
|execvp()|&co. explicitly operate on '\0'-terminated strings to allow
applications to pass _any_ types of data to the process being invoked
and |exec_system()| shouldn't restrict this in any way (see below, at
least for multibyte locales you're running in a very special kind of
hell...) ...

> But for whitespaces, no other shell meta-characters will be supported by
> the exec_system() function.

What do you mean in this case ? Does |exec_system()| do any special
handling of shell meta-characters (and _which_ shell do you mean ?
Bourne shell, csh, zsh, Korn Shell, POSIX shell standard) ?

> When used inside a setuid program, the exec_system() function will drop
> privileges to those of the real user while executing the file/command.
> 
> To avoid potential execution of arbitrary binaries in user defined PATH,
> exec_system() will mandate that an absolute path to be executable be
> supplied while calling the function.
> 
> The exec_system() implementation will extend the signal handling model
> of system(3C) and will set SIGCHLD to be blocked for the calling thread,
> while waiting for the file execution to terminate. Unlike the
> system(3C), SIGINT and SIGQUIT will be ignored only in the child
> process, making the function MT-safe. This project will use the new
> posix_spawn() extensions implemented via PSARC/2008/617 (posix_spawn
> extension - setsigignore).
> 
> The exec_system() function is not designed to be a replacement for the
> system(3C) function. The new function should be recommended for
> execution of files that do not require the shell. This will help prevent
> potential vulnerabilities arising due to malicious environment variables
> and special characters in user inputs.

Erm... some questions:
- How do you handle the case if someone wants to use '\377' as plain
value ?
- How do you handle the case if a multibyte locale uses '\377' for
different purposes ?

IMO it may be better to change |exec_system()| to take a traditional
argv as argument, e.g. |int exec_system(const char *application,
uint32_t, const char *argv[], ...)| (the |flags| would allow further
modifications to the interface and the ellipsis allows to pass more
arguments in future revisions).

----

Bye,
Roland

-- 
  __ .  . __
 (o.\ \/ /.o) roland.mainz at nrubsig.org
  \__\/\/__/  MPEG specialist, C&&JAVA&&Sun&&Unix programmer
  /O /==\ O\  TEL +49 641 3992797
 (;O/ \/ \O;)

Reply via email to