Casper.Dik at Sun.COM wrote on 05/29/09 06:11:

>>      system_noshell(const char *abs_path);
>>
>>      system_noshell_x(const char *abs_path, uint_t flags, const char *arg0,
>>          ... /* const char *argn, (char *)0 */);
>>
>>      system_noshell_xv(const char *abs_path, uint_t flags,
>>          char *const argv[]);
>>
> 
> 
> Are these wrappers for posix_spawn?  And why can't we use posix_spawn as 
> it is?
> 

Not a simple wrapper for posix_spawn() but with a few more enhancements:

 + Three separate interfaces depending on the use cases.
 + Mandating absolute path to the file being executed.
 + Dropping privileges in the default system_noshell() function to those
   of the real user, similar to system(3C) and unlike posix_spawn() or
   exec() family of functions.
 + Unrelated to posix_spawn(), but system_noshell*() functions mirror
   system(3C) behavior of ignoring SIGINT and SIGQUIT, but they do it
   only in the child making the functions MT-safe unlike system(3C).

>       posix_swap(&pid, abs_path, NULL, NULL, argv, NULL) is nearly the 
> same as system_noshell_vx.
> 

True, but that's just for system_noshell_xv() (besides the fact that
posix_spawn() doesn't provide any secure features). This comes along
with 2 more interfaces which are simpler to read and use depending on
the use case.

Also, posix_spawn() comes with a longer string of arguments and more
verbose and harder to read man page than system_noshell(). Agreed that
posix_spawn() gives greater flexibility in the argument vector, but
system_noshell() is more directed towards avoiding system(3C) usage that
lead to security vulnerabilities.

> If people don't use posix_spawn, why do you suspect they will use
> system_no_shell*?
> 

The basic system_noshell() prototype provides a significantly simpler
interface than posix_spawn(). For instance,

system_noshell("/bin/rm /tmp/tmpfile") is simpler than
posix_spawn(pid, "rm", NULL, NULL, argv, NULL) which also includes
populating an argv vector.

posix_spawn() implementation is also verbose and prone to mistakes. For
instance, see the "invoke_rm()" function in the file
usr/src/cmd/saf/sacadm.c. Such operations may be done using a one-liner
with system_noshell().

I think people shy away from posix_spawn() due to the above mentioned
reasons and opt to use the simpler system(3C) interface.
system_noshell() will provide equally simple interfaces while preventing
commonly seen vulnerabilities.

> Where is the environment set?
> 

This comes from the default __environ in the process space.

> Why are the _x and _xv suffices more like exec():
> 
>       (execl, execv: l for list, v for a vector)
> 

They are.

The system_noshell() set of functions are _not_ designed to replace
system(3C), posix_spawn(3C) or exec() family of functions. They are
designed to be a *secure alternative* to system(3C) while provide the
ease of use of system(3C). posix_spawn() and fork()/exec()/waitpid() are
verbose and in the real world, programmers avoid them.

We (security coordination team) often see programmers use system(3C) in
insecure ways. This may be seen in code as recent as the fast reboot
putback and the other bugs listed.

I would draw parallel to the need for a new strlcpy() interface when we
already have a strcpy() or a strncpy(). Security guidelines say that
destination buffer should always be verified and strings should NUL
terminated, but they aren't in the real world. Hence the need for a
strlcpy().

-Sumanth

Reply via email to