HomePhabricator

Refine checks against "cwd" before "proc_open()"

Description

Refine checks against "cwd" before "proc_open()"

Summary:
See PHI1094. Previously, see D15785. Fixes T10853. Upstream: https://bugs.php.net/bug.php?id=77656.

PHP allows you to proc_open() into any CWD, including one that does not exist, is not readable, and/or is not executable.

We attempt to catch this, but don't do enough checks, and allow you to attempt execution into a directory which exists but which you can't read or execute.

Add more checks to prevent this. Also, try to make assertExists() more clever about cases where a path really doesn't exist versus cases where we aren't allowed to tell if a path exists or not because of a permissions issue.

(It's technically legal to chdir() into a directory you only have +x on, although this is probably ill-advised.)

Test Plan:
Used this script with various arguments:

<?php

require_once '/Users/epriestley/dev/phabricator/scripts/init/init-script.php';

$result = id(new ExecFuture('pwd && ls -alh'))
  ->setCWD($argv[1])
  ->resolvex();

var_dump($result);

In all cases, the directory name describes the permissions. subdir/ exists and is a directory we have "+r" and "+x" on.

epriestley@orbital ~/scratch $ php -f pwd2.php /Users/epriestley/scratch/not-readable
[2019-02-22 15:34:14] EXCEPTION: (Exception) Preparing to run a command in directory "/Users/epriestley/scratch/not-readable", but that directory is not readable (the current process does not have "+r" permission). at [<phutil>/src/future/exec/PhutilExecutableFuture.php:156]
epriestley@orbital ~/scratch $ php -f pwd2.php /Users/epriestley/scratch/not-readable/subdir
array(2) {
  [0]=>
  string(163) "/Users/epriestley/scratch/not-readable/subdir
total 0
drwxr-xr-x  2 epriestley  staff    64B Feb 22 15:33 .
drwxr-x--x  3 root        wheel    96B Feb 22 15:33 ..
"
  [1]=>
  string(0) ""
}
epriestley@orbital ~/scratch $ php -f pwd2.php /Users/epriestley/scratch/not-executable
[2019-02-22 15:34:24] EXCEPTION: (Exception) Preparing to run a command in directory "/Users/epriestley/scratch/not-executable", but that directory is not executable (the current process does not have "+x" permission). at [<phutil>/src/future/exec/PhutilExecutableFuture.php:165]
epriestley@orbital ~/scratch $ php -f pwd2.php /Users/epriestley/scratch/not-executable/subdir
[2019-02-22 15:34:26] EXCEPTION: (PhutilProxyException) Unable to run a command in directory "/Users/epriestley/scratch/not-executable/subdir". {>} (FilesystemException) Filesystem path "/Users/epriestley/scratch/not-executable/subdir" can not be accessed because a parent directory ("/Users/epriestley/scratch/not-executable") is not executable (the current process does not have "+x" permission). at [<phutil>/src/filesystem/Filesystem.php:1142]
epriestley@orbital ~/scratch $ php -f pwd2.php /Users/epriestley/scratch/not-readable-or-executable/
[2019-02-22 15:34:32] EXCEPTION: (Exception) Preparing to run a command in directory "/Users/epriestley/scratch/not-readable-or-executable/", but that directory is not readable (the current process does not have "+r" permission). at [<phutil>/src/future/exec/PhutilExecutableFuture.php:156]
epriestley@orbital ~/scratch $ php -f pwd2.php /Users/epriestley/scratch/not-readable-or-executable/subdir
[2019-02-22 15:34:33] EXCEPTION: (PhutilProxyException) Unable to run a command in directory "/Users/epriestley/scratch/not-readable-or-executable/subdir". {>} (FilesystemException) Filesystem path "/Users/epriestley/scratch/not-readable-or-executable/subdir" can not be accessed because a parent directory ("/Users/epriestley/scratch/not-readable-or-executable") is not executable (the current process does not have "+x" permission). at [<phutil>/src/filesystem/Filesystem.php:1142]
epriestley@orbital ~/scratch $ php -f pwd2.php /Users/epriestley/scratch/does-not-exist
[2019-02-22 15:34:37] EXCEPTION: (PhutilProxyException) Unable to run a command in directory "/Users/epriestley/scratch/does-not-exist". {>} (FilesystemException) Filesystem path "/Users/epriestley/scratch/does-not-exist" does not exist. at [<phutil>/src/filesystem/Filesystem.php:1153]

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T10853

Differential Revision: https://secure.phabricator.com/D20205