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