Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:44492 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 52996 invoked from network); 26 Jun 2009 21:21:02 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 26 Jun 2009 21:21:02 -0000 Authentication-Results: pb1.pair.com header.from=gwynne@darkrainfall.org; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=gwynne@darkrainfall.org; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain darkrainfall.org from 208.97.132.81 cause and error) X-PHP-List-Original-Sender: gwynne@darkrainfall.org X-Host-Fingerprint: 208.97.132.81 caiajhbdcaib.dreamhost.com Linux 2.6 Received: from [208.97.132.81] ([208.97.132.81:52859] helo=homiemail-a14.g.dreamhost.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 2A/28-08868-CBB354A4 for ; Fri, 26 Jun 2009 17:21:01 -0400 Received: from Moonstar.home (pool-71-174-84-161.bstnma.fios.verizon.net [71.174.84.161]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by homiemail-a14.g.dreamhost.com (Postfix) with ESMTPSA id 4E5968C06D for ; Fri, 26 Jun 2009 14:20:57 -0700 (PDT) Message-ID: To: PHP internals Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v935.3) Date: Fri, 26 Jun 2009 17:20:56 -0400 X-Mailer: Apple Mail (2.935.3) Subject: A patch for HEAD From: gwynne@darkrainfall.org (Gwynne Raskind) I've just finished making this patch for my own use (diffed against 5.3 CVS): http://darkrainfall.org/php-5.3-shellbypass.patch In short, what it does is make proc_open()'s shell_bypass option available to UNIX systems. This is accomplished by allowing the "command" parameter to proc_open() to be an array of arguments to pass to execv[e](). I've included a few tests to check the functionality. (A few more tests could be devised to, for example, check that the correct warning is issued if you pass an array without bypass_shell set, or a string with it set, etc.) The exact behavior of the argument array is: 1) The array must contain at least one element, at index 0. 2) The element at index 0 is always the exact command path passed to execv[e]() (after being filtered through any safe_mode restrictions, as with the normal behavior of proc_open()). 3) Any other elements form the argv array passed to execv[e](). By convention the first of these arguments (argv[0] in the child process) is the same as the command path, however my patch does NOT enforce or assume this; it simply calls execv[e]($argument_array[0], array_slice($argument_array, 1)). This patch currently provides the only useful way to fork a process without running a shell (pcntl_fork() + pcntl_exec() are useless since there's no pcntl_dup2() to control the descriptors of the child). Why would you want to avoid the shell? - Efficiency. The shell is an extra, often unnecessary process, which must parse the commandline given to it into individual arguments according to all its various rules. Not to mention the overhead of setting up another entire process just to run a third process. - Resource control. The shell is an extra process. If you don't need it, and your system is tight on process space, best to avoid it. - Sanity. Correctly quoting arguments to a shell command ranges from mildly annoying (escapeshellarg() in simple cases) to nightmarish (manual parsing of a string in some edge cases). Passing arguments directly completely bypasses this, quite possibly saving you quite a bit of string parsing time if you were doing something like "$shell_args = implode(' ', array_map('escapeshellarg', $raw_args));". - Oddly enough, security. Since there's no shell, it's more difficult to subvert the child process to do other things than the coder intended (unless of course, said coder executes a shell this way). This patch does nothing on Windows, since the option was already implemented there. It also does nothing on Netware, since from what I could see in the code, Netware doesn't have a shell in the first place. I'm proposing the inclusion of this patch in HEAD (which I'll port it to if I get a thumbs-up here), and possibly 5.3.2. Criticism and angry flames welcome. Constructive critcism and good-natured comments will be ignored ;) (just kidding... or am I?). -- Gwynne