Template Version: @(#)sac_nextcase 1.68 02/23/09 SMI This information is Copyright 2009 Sun Microsystems 1. Introduction 1.1. Project/Component Working Name: system_noshell 1.2. Name of Document Author/Supplier: Author: Sumanth Naropanth 1.3 Date of This Document: 29 May, 2009 4. Technical Description I'm sponsoring this fasttrack on behalf of Sumanth Naropanth. This case will time out June 5, 2009.
SUMMARY: Implementation of new C library functions -- system_noshell(3C) (and variants) to work as secure alternatives to the system(3C) function, to proactively prevent security vulnerabilities resulting from unintended invocation of user shell. PROBLEM: The system(3C) function call invokes the user shell to execute the argument string supplied to it. This function, however is frequently used to execute a file when there is no need to invoke the shell at all. Searching through the OpenSolaris source files for the usage of the system(3C) function produces over 200 hits, a large number of which are binary executions which should rather be done in a safer way via the exec(2) family of system calls. If not used carefully, the system(3C) function may be responsible for the following security concerns: + Execution of the command is affected by the PATH, IFS and other environment variables. + Special characters may intentionally be injected in cases where system() is called on unsanitized user input, causing system() to potentially execute arbitrary commands. Here are a few results from searching through the Sun Bugtraq database for security bugs due to poor usage of system(): 1. CR 6472377: use of system() can cause execution of arbitrary code through malformed filenames (CVE-2006-0225) 2. CR 6438834: Unsafe code in *sacadm* may lead to escalation of privileges under specific conditions 3. CR 6751653 reboot -f -e introduces new system() calls 4. CR 6473508 rcp(1) use of 'sh -c' in execl() can cause execution of arbitrary code through malformed filenames 5. CR 6754889 user{add, mod, del} sources should use absolute paths 6. CR 4897594 PGX-32 DDX should not call system() All these bugs describe unsafe and incorrect usage of system(3C), where it's rather advisable to use fork()/exec()/wait(). The list of C library functions at http://secprog.sfbay/funclist.html currently tags the system() function call as 'AVOID' and does not list an 'alternative'. PROPOSED SOLUTION: The system_noshell(3C) function call will be implemented to provide the same ease of use as the system(3C) function, via a single (const char *) argument. Variants of this function will be system_noshell_x(3C) and system_noshell_xv(3C) which will allow for special arguments to be passed while executing a file. Prototypes: ----------- 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[]); The system_noshell_x() allows variable number of arguments and can be used to supply argument strings containing special characters (including whitespaces and quotes) literally. The system_noshell_xv() allows for the same functionality with an execv(2) style array of pointers to null-terminated strings. The 'flags' field may be used to pass the value 'SN_RESETIDS' to reset the process's effective user and group IDs to the real IDs. Without this flag, the process will run with the privileges of the effective user and effective group. These new functions provide greater security in comparison with the system() function by avoiding user shell invocation. No shell metacharacters will be supported. The file execution happens via posix_spawn(3C)/waitpid(3C). When used inside a setuid program, the system_noshell(3C) function executes just like the system(3C) function by dropping privileges to those of the real user, instead of running with the privileges of the effective user. Use the extended variants of the function to override this behavior. To avoid potential execution of arbitrary binaries, the system_noshell(3C) and its variant functions mandate that an absolute path be supplied to the binary being executed. As with the system(3C) function, the system_noshell(3C) and variant functions set SIGCHLD to be blocked for the calling thread, while waiting for the file execution to terminate. Unlike the existing system(3C) implementation however, the system_noshell*() functions set SIGINT and SIGQUIT to be ignored only in the child process, making them MT-safe. The system_noshell*(3C) functions are not designed to be a replacement for the system(3C) function. The new functions should be recommended for execution of files that do not require the shell. BINDING: This case seeks a minor release binding. COMMITMENT LEVEL: ------------------------------------------------------- | Interface | Commitment Level | ------------------------------------------------------- | system_noshell() | Committed | | system_noshell_x() | Committed | | system_noshell_xv() | Committed | ------------------------------------------------------- REFERENCE DOCUMENTS: See man page for system_noshell(3C) in case materials. 6. Resources and Schedule 6.4. Steering Committee requested information 6.4.1. Consolidation C-team Name: ON 6.5. ARC review type: FastTrack 6.6. ARC Exposure: open