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;)
