Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #65069: GlobIterator fails to access files inside an open_basedir restricted dir #398

Closed
wants to merge 7 commits into from

Conversation

4 participants
@bukka
Copy link
Member

commented Jul 28, 2013

Proper checking and filtering of glob stream paths when open_basedir set

@weltling

This comment has been minimized.

Copy link

commented on ext/spl/tests/bug65069.phpt in 86cbcef Jul 29, 2013

comparing arrays with paths might not work on windows where '/' and '' might be mixed

@weltling

This comment has been minimized.

Copy link

commented on ext/spl/tests/bug65069.phpt in 86cbcef Jul 29, 2013

I'd suggest to iterate over files that don't change during test, otherwise the gap between glob() call and iterator instantiation might bring this test to fail in parallel test runs.

@weltling

This comment has been minimized.

Copy link

commented on main/streams/glob_wrapper.c in 86cbcef Jul 29, 2013

if (NULL == pglob->basedir_indexmap) ....

@weltling

This comment has been minimized.

Copy link

commented on main/streams/glob_wrapper.c in 86cbcef Jul 29, 2013

  1. This will throw a warning if glob()'s result is empty
  2. Shouldn't it be an exception in the object context?
@weltling

This comment has been minimized.

Copy link
Contributor

commented Jul 29, 2013

Great to see ones hands on this bug, nice idea for the fix. Please take the comments above into account. Also i think you should add more tests, like with the empty glob result, '.' as basedir, pattern is completely outta basedir, ... may be you could see more in ext/standard/tests/file/glob_* ...

One thing i wonder though - why do you need to deal with two indexes? You could save only valid indexes in the map and use those for iterator instead of the originals delivered by glob(). That would also spare recording the first element, only the map array and its size were needed.

@bukka

This comment has been minimized.

Copy link
Member Author

commented Jul 29, 2013

Thanks for comments! I will look into this a bit later (probably tonight). I planed to do some changes anyway.

About the indexes. The thing is that if I don't want to check valid paths twice or use reallocations during the checking, I need to allocate pglob->glob.gl_pathc elements. In case I wanted to save indexes, I would have to use int and map would be 4 times or 8 times (64bit) bigger. I actually thought about binary map when I started with implementation but compare to data allocated by glob, it's just not worthy implementation... I know that memory is not an issue so using index map wouldn't be problem. I also know that iterating would be more performance friendly if I used int map with indexes.

Because both of these things have minor influence (because the slowest and the memory most expensive operation is glob), I think that the best would be to choose a solution that is easier to understand when you read the code. I thought that masking is simpler but if you think that indexes would be better, I am happy to implement it?

@weltling

This comment has been minimized.

Copy link
Contributor

commented Jul 29, 2013

As for me, i'd be standing for a simpler code more than for sparse memory, at least as long as it's acceptable. Having something like pglob->valid_idx and checking only for pglob->valid_idx_size would also minimize error risks . IMHO, lets wait for other comments.

@bukka

This comment has been minimized.

Copy link
Member Author

commented Jul 29, 2013

I have fixed the things that you mentioned (if I forgot something let me know). It looks that saving of indexes is much more readable. It also is a bit shorter. Just need to do a proper testing. I will add more tests later (probably tomorrow).

@bukka

This comment has been minimized.

Copy link
Member Author

commented Jul 30, 2013

I have just added more tests and last fixes. I think that the patch is ok now. If there is anything else, let me know!

@weltling

This comment has been minimized.

Copy link

commented on main/streams/glob_wrapper.c in 3dc5e37 Aug 14, 2013

At the current stage the test still fails for me, and looking here i know why - php_check_open_basedir_ex() doesn't belong here at all. In the case user passes nonexistent pattern path, glob.gl_pathc == 0 and that's enough.Otherwise if user passes a direct path, glob.gc_pathc == 1. In any case basedir check is done in the loop for each expanded path. Open basedir check on a pattern path is the initial mistake you're fixing ;)

@weltling

This comment has been minimized.

@bukka

This comment has been minimized.

Copy link
Member Author

commented Aug 14, 2013

Please could you provide an example when it fails? The test bug65069.phpt contains example ($spl_glob_empty = ...) and test passed for me. Have you tried this test or have you got a different situation? If this test fail, couldn't be the reason using slashes as a directory separator (if you run it on win)?

There is a security reason why using php_check_open_basedir_ex() is necessary. There is a different exception when you have an empty result ( glob.gl_pathc == 0 ) - LogicalException and when you try to find paths that are out of open_basedir directory (php_error_docref converted to exception). If you test only the empty result, then non-existence of files out of the open_basedir could be tested (see test part: $spl_glob_sec = ...). I actually add this to the comment that is above the condition but not sure if it's clear enough :).

@weltling

This comment has been minimized.

Copy link
Contributor

commented Aug 15, 2013

That's in the test you mention, the place with *.php. glob returns GLOB_NOMATCH, so indexmap is NULL, glob.path_c is zero and php_check_open_basedir_ex() returns -1, together (1 && (0 || -1)) which leads to the openbasedir warning.

That -1 is because php_check_open_basedir_ex() used with a pattern path 'dir/*.php', this is the error you actually fixing. It works somehow :) but IMHO is fundamentally wrong, they do it similar way in http://lxr.php.net/xref/PHP_TRUNK/ext/standard/dir.c#492 . But i can tell you why it's -1 on windows, here's the BT

php5ts_debug.dll!virtual_file_ex(_cwd_state * state, const char * path, int (const _cwd_state *) * verify_path, int use_realpath, void * * * tsrm_ls) Line 1243 C
php5ts_debug.dll!expand_filepath_with_mode(const char * filepath, char * real_path, const char * relative_to, unsigned __int64 relative_to_len, int realpath_mode, void * * * tsrm_ls) Line 792 C
php5ts_debug.dll!expand_filepath_ex(const char * filepath, char * real_path, const char * relative_to, unsigned __int64 relative_to_len, void * * * tsrm_ls) Line 741   C
php5ts_debug.dll!expand_filepath(const char * filepath, char * real_path, void * * * tsrm_ls) Line 733  C
php5ts_debug.dll!php_check_specific_open_basedir(const char * basedir, const char * path, void * * * tsrm_ls) Line 167  C
php5ts_debug.dll!php_check_open_basedir_ex(const char * path, int warn, void * * * tsrm_ls) Line 320    C
php5ts_debug.dll!php_glob_stream_opener(_php_stream_wrapper * wrapper, char * path, char * mode, int options, char * * opened_path, _php_stream_context * context, int __php_stream_call_depth, const char * __zend_filename, const unsigned int __zend_lineno, const char * __zend_orig_filename, const unsigned int __zend_orig_lineno, void * * * tsrm_ls) Line 261  C
php5ts_debug.dll!_php_stream_opendir(char * path, int options, _php_stream_context * context, int __php_stream_call_depth, const char * __zend_filename, const unsigned int __zend_lineno, const char * __zend_orig_filename, const unsigned int __zend_orig_lineno, void * * * tsrm_ls) Line 1975  C
php5ts_debug.dll!spl_filesystem_dir_open(_spl_filesystem_object * intern, char * path, void * * * tsrm_ls) Line 247 C
php5ts_debug.dll!spl_filesystem_object_construct(int ht, _zval_struct * return_value, _zval_struct * * return_value_ptr, _zval_struct * this_ptr, int return_value_used, void * * * tsrm_ls, long ctor_flags) Line 724  C
php5ts_debug.dll!zim_spl_GlobIterator___construct(int ht, _zval_struct * return_value, _zval_struct * * return_value_ptr, _zval_struct * this_ptr, int return_value_used, void * * * tsrm_ls) Line 1605 C

There is a specific check for some wildcards in the path when it enters virtual_file_ex(). Could you pls recheck with the glob implementation? It throws no warning and just silently return false, therefore no platform difference. Maybe it should be done the same way glob does, like an early return right after glob was NOMATCH? So like in the glob() function.

@bukka

This comment has been minimized.

Copy link
Member Author

commented Aug 17, 2013

I just double checked the glob implementation. glob logic the same as my implementation of the glob_wrapper.

glob return values are following:

  • array of paths
  • empty array if no pattern is found
  • false
    • if directory the directory out of open_basedir is searched (our case)
    • if the C glob return value is different than 0 and GLOB_NOMATCH (which means glob error)

this patch deals with that in this way:

  • iterator of paths
  • empty iterator (return null) - count throw LogicException
  • open_basedir warning converted to Exception
    • if directory the directory out of open_basedir is searched (our case)
    • if the C glob return value is different than 0 and GLOB_NOMATCH (which means glob error)

As you can see the problem is in both functions. glob shouldn't return false but an empty array. I just tested it on Linux and it really returns an empty array so there is a platform difference.

As I said the logic is the same with one small difference (see bellow). There is the same test on the pattern http://lxr.php.net/xref/PHP_TRUNK/ext/standard/dir.c#495 that is executed if path_c is equal to 0 or result is equal to GLOB_NOMATCH (this is actually the only difference with the patch that in case that GLOB_NOMATCH is returned by glob, the paths are tested before the pattern. The glob uses goto and test the pattern immediately. Not sure if it could be a problem because path_c should be 0 anyway but not sure if there are some platforms where this deosn't have to be so. I can add it if you think that it could be a problem?).

Anyway back to the our problem. I think that there is a bug in glob implementation on Windows. Possibly bug in virtual_file_ex because it behaves differently on win and linux. I think that glob_wrapper and glob should have the same behavior. We should fix it in both functions though. The best place would be php_check_specific_open_basedir where we could check for wildcards. I could do that if you want? Possibly changing virtual_file_ex could solve the problem as well because its behavior is platform specific but this would need to be done by someone who can test it on win as I don't have win... What do you think?

@weltling

This comment has been minimized.

Copy link
Contributor

commented Aug 18, 2013

Finally prepared the env to test on both linux and windows, please check this

on linux

`$ sapi/cli/php -n -d open_basedir=/home/anatol/dws/src/bukka/ext/spl/tests/bug65069/ -r 'var_dump(new GlobIterator("/home/anatol/dws/src/bukka/ext/spl/tests/bug65069/.php"));'
object(GlobIterator)#1 (3) {
["pathName":"SplFileInfo":private]=>
string(0) ""
["glob":"DirectoryIterator":private]=>
string(62) "glob:///home/anatol/dws/src/bukka/ext/spl/tests/bug65069/
.php"
["subPathName":"RecursiveDirectoryIterator":private]=>
string(0) ""
}

$ sapi/cli/php -n -d open_basedir=/home/anatol/dws/src/bukka/ext/spl/tests/bug65069/ -r 'var_dump(glob("/home/anatol/dws/src/bukka/ext/spl/tests/bug65069/*.php"));'
array(0) {
}`

the same on windows

`x64\Debug_TS\php -n -d open_basedir=C:\php-sdk\phpmaster\vc11\x64\bukka\ext\spl\tests\bug65069 -r "var_dump(new GlobIterator('C:\php-sdk\phpmaster\vc11\x64\bukka\ext\spl\tests\bug65069*.php'));"

Fatal error: Uncaught exception 'UnexpectedValueException' with message 'GlobIterator::__construct(): open_basedir restriction in effect. File(C:\php-sdk\phpmaster\vc11\x64\bukka\ext\spl\tests\bug65069*.php) is not within the allowed path(s): (C:\php-sdk\phpmaster\vc11\x64\bukka\ext\spl\tests\bug65069)' in Command line code:1
Stack trace:
#0 Command line code(1): GlobIterator->__construct('C:\php-sdk\phpm...')
#1 {main}
thrown in Command line code on line 1

x64\Debug_TS\php -n -d open_basedir=C:\php-sdk\phpmaster\vc11\x64\bukka\ext\spl\tests\bug65069 -r "var_dump(glob('C:\php-sdk\phpmaster\vc11\x64\bukka\ext\spl\tests\bug65069*.php'));"
bool(false)`

Ok, so that's probably not what i thought last time. However you see teh difference, there has to be something in the code flow causing it. Also note the behaviour is only reproduceable with the full paths and only if the pattern points to non existent files in the root of basepath.

However, checking the same glob() call on PHP-5.5 it returns bool(false) on both windows and linux. I haven't checked the history yet, but master is clearly breaking BC. The question is if that's intended and accepted. Possibly the behaviour of glob() has to be fixes as well then.

Aside that, i'd really speak for leaving the virtual_file_ex() and co alone. Not only it's not the topic of this ticket. The behaviour there, as you say, is based on many platform specific things, and even if not - any change will have beyond consequences. What you call bug might be a survival thing :), like '*' and '?' are inacceptable for the NTFS filesystem. Much better to solve it right in place using #ifdef if necessary.

Thanks.

@pierrejoye

This comment has been minimized.

Copy link
Contributor

commented Aug 19, 2013

hi!

"The best place would be php_check_specific_open_basedir where we could check for wildcards. I could do that if you want?"

That's not a good choice, this function only checks a given path and tells if it is inside the open base dirs or not. Adding glob-like support to it makes it over complicated and will slow down almost all file ops.

"Possibly changing virtual_file_ex could solve the problem as well because its behavior is platform specific but this would need to be done by someone who can test it on win as I don't have win... What do you think?"

Which kind of platform specific behaviors do you see exactly?

@weltling

This comment has been minimized.

Copy link
Contributor

commented Aug 19, 2013

@bukka

This comment has been minimized.

Copy link
Member Author

commented Aug 19, 2013

I think that the best solution would be create a new PHPAPI exported function in /main/fopen_wrappers.c. Something like:

PHPAPI int php_check_open_basedir_pattern_ex(const char *pattern, int warn TSRMLS_DC);

that would use (when call php_check_open_basedir_ex) only part of the path that dosn't contain wildcards (in your case /home/anatol/dws/src/bukka/ext/spl/tests/bug65069/). This function would be used in glob and glob_wrapper for the pattern check. It should resolve the bug.

I will send a patch later if you agree with the solution?

@pierrejoye

This comment has been minimized.

Copy link
Contributor

commented Aug 19, 2013

hi!

On Mon, Aug 19, 2013 at 1:28 PM, Jakub Zelenka notifications@github.comwrote:

I think that the best solution would be create a new PHPAPI exported
function in /main/fopen_wrappers.c. For example:

PHPAPI int php_check_open_basedir_pattern_ex(const char *pattern, int warn TSRMLS_DC);

that would use (when call php_check_open_basedir_ex) only part of the
path that dosn't contain wildcards (in your case
/home/anatol/dws/src/bukka/ext/spl/tests/bug65069/). This function would
be used in glob and glob_wrapper for pattern check. It should resolve the
bug.

I will send a patch later if you agree with the solution?


Reply to this email directly or view it on GitHubhttps://github.com//pull/398#issuecomment-22865573
.

Not really, this function just like virtual_file_ex should care only about
actual path, nothing else. Its complexity and high sensible usage should
not allow adding such features.

That being said, we found the actual source of a bug, Anatolyi is
finalizing a patch.

Pierre

@pierrejoye | http://www.libgd.org

@bukka

This comment has been minimized.

Copy link
Member Author

commented Aug 19, 2013

Hi,

Ok great. That makes sense. Let me know if there is anything that should be done in this patch.

@weltling

This comment has been minimized.

Copy link
Contributor

commented Aug 19, 2013

@bukka please consider these patch to glob() and the test

http://git.php.net/?p=php-src.git;a=commitdiff;h=f4df40108be641a4167f6f6c1c3989958dda438a
http://git.php.net/?p=php-src.git;a=blob_plain;f=ext/standard/tests/file/glob_variation3.phpt;hb=refs/heads/master

The lesson learned is that we shouldn't bother for windows with the basedir check on the glob query. If that query contains illegal path chars, it's justified to get an error. As you can see from the test, in case of windows if glob() returned nomatch, return an empty array() without further checks. That way the test linked above passes on linux and windows.

So in your patch, you could make an early return just using that five lines from the glob(), or #ifndef that basedir check on windows correspondingly.

Cheers

@bukka

This comment has been minimized.

Copy link
Member Author

commented Aug 19, 2013

I am afraid that glob_variation3.phpt is wrong. The problem is that you can't change open_basedir if you have set it before (don't know why but it works like that on my Linux build (maybe another bug)... :) ). It means that the changing open_basedir path to /tmp doesn't work - try var_dump(ini_get('open_basedir')); after ini_set('open_basedir', '/tmp');.

If you test only this:

<?php
$path = dirname(__FILE__);
ini_set('open_basedir', '/tmp');
var_dump(glob("$path/*.none"));
var_dump(glob("$path/?.none"));
var_dump(glob("$path/*{hello,world}.none"));
var_dump(glob("$path/*/nothere"));
var_dump(glob("$path/[aoeu]*.none"));
var_dump(glob("$path/directly_not_exists"));

the result is false for all calling of glob on Linux and I guess that it will be an empty array on Windows (That's because you don't test the pattern). The linux behaviour is correct because testing files that are not in open_basedir directory is error (not empty result). What you can actually do on Win now is finding existing file that is not in open_basedir. Try glob(__FILE__). It should give you false now. It's just my guess - I haven't tested it.

In this case the point of testing the pattern is not to find out whether the whole pattern is in open_basedir but whether its directory (in this case $path) is in open_basedir which could be considered as a security bug. The whole thing is a bit more complicated if you test patterns like /home/*/test/*/*.php when open_basedir is /home/jakub/test. Then glob needs to be run recursively to decide whether the result should be false or empty array (in this example obviously an empty array).

I have got an idea how to do that. I could implement it as a part of this patch to glob_wrapper and after testing on win, we can do similar implementation in glob implementation. What do you think?

@pierrejoye

This comment has been minimized.

Copy link
Contributor

commented Aug 19, 2013

You can change it, but only make it more restrictive. See the doc for more
details.
On Aug 19, 2013 9:14 PM, "Jakub Zelenka" notifications@github.com wrote:

I am afraid that glob_variation3.phpt is wrong. The problem is that you
can't change open_basedir if you have set it before (don't know why but
it works like that on my Linux build (maybe another bug)... :) ). It means
that the changing open_basedir path to /tmp doesn't work - try
var_dump(ini_get('open_basedir')); after ini_set('open_basedir', '/tmp');.

If you test only this:

@weltling

This comment has been minimized.

Copy link
Contributor

commented Aug 20, 2013

@bukka, ok, if the pattern looks like '{/hello,/world}*' .... how do you check it with the real basedir path? Or any other complex pattern. Assumed that pattern is nomatch and basedir set to /hello or /somewhere, i doubt php_check_open_basedir_ex() has sense even on linux in this case :)

@bukka

This comment has been minimized.

Copy link
Member Author

commented Aug 20, 2013

Yeah I was thinking about these cases and they are a bit tricky. We would have to parse the path when calling glob recursively. For example if you have something like this: dir = {/hello,/world}*/one/*/two/*.php and open_basedir=/somewher. Then you would do this:

  1. glob('{/hello,/world}/one//two/*.php') - if empty goto 2, otherwise check paths
  2. glob('{/hello,/world}/one//two/') - if empty goto 3, otherwise check paths
  3. check paths for /hello/one and /world/one (it means expansion for brace patterns.)

The question is if this complex checking is not a bit too much..?

Other and maybe better solution would be returning an empty array in any case. It means even if the open_basedir test fails - http://lxr.php.net/xref/PHP_TRUNK/ext/standard/dir.c#537 (That would prevent security risk of checking file existence out of open_basedir directory) We would just didn't consider searching out of open_basedir as an error but only return empty result...? That would actually resolve the initial request in bug 47358.

@pierrejoye

This comment has been minimized.

Copy link
Contributor

commented Aug 20, 2013

On Tue, Aug 20, 2013 at 11:05 AM, Jakub Zelenka notifications@github.comwrote:

Yeah I was thinking about these cases and they are a bit tricky. We would
have to parse the path when calling glob recursively. For example if you
have something like this: dir = {/hello,/world}/one//two/*.php and
open_basedir=/somewher. Then you would do this:

  1. glob('{/hello,/world}/one//two/*.php') - if empty goto 2,
    otherwise check paths
  2. glob('{/hello,/world}/one//two/') - if empty goto 3, otherwise
    check paths
  3. check paths for /hello/one and /world/one (it means expansion for
    brace patterns.)

The question is if this complex checking is not a bit too much..?

It means rewrite glob for every single supported platform.

Other and maybe better solution would be returning an empty array in any
case. It means even if the open_basedir test fails -
http://lxr.php.net/xref/PHP_TRUNK/ext/standard/dir.c#537 (That would
prevent security risk of checking file existence out of open_basedir
directory) We would just didn't consider searching out of open_basedir as
an error but only return empty result...? That would actually resolve the
initial request in bug 47358.

imho, the solution is to do these checks using the results, not the
patterns. If one should not be visible nor telling if it exists or not
(open_basedir), return false.


Reply to this email directly or view it on GitHubhttps://github.com//pull/398#issuecomment-22931461
.

Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

@bukka

This comment has been minimized.

Copy link
Member Author

commented Aug 20, 2013

The problem is what to return if you don't have the result...?

I haven't shown any example how this be a security risk yet.

Please consider this:
open_basedir = /tmp
then you have got this existing file in your directory: /var/test/index.html (it's the only file in the directory /var/test
Now you have this script

<?php
var_dump(glob('/var/test/index.html'));
var_dump(glob('/var/test/*.php'));

then if don't test the pattern, the result is following

bool(false)
array(0) {
}

You can see that we shouldn't get any information if the file exists because open_basedir is /tmp.

We need to agree how the empty results will be handled. Either we keep returning false if the testing is out of open_basedir (in that case we have to check the pattern and implement complex logic - example above), or we return an empty array (then we don't have to check the pattern).

@pierrejoye

This comment has been minimized.

Copy link
Contributor

commented Aug 20, 2013

On Aug 20, 2013 11:40 AM, "Jakub Zelenka" notifications@github.com wrote:

The problem is what to return if you don't have the result...?

I haven't shown any example how this be a security risk yet.

Please consider this:
open_basedir = /tmp
then you have got this existing file in your directory:
/var/test/index.html (it's the only file in the directory /var/test
Now you have this script

That's where there are inconsistencies and they should be fixed.

We need to agree how the empty results will be handled. Either we keep
returning false if the testing is out of open_basedir (in that case we have
to check the pattern and implement complex logic - example above), or we
return an empty array (then we don't have to check the pattern).

Again it won't happen.

And yes, false should be returned if any resulting path are outside open
basedir. Or?


Reply to this email directly or view it on GitHub.

@bukka

This comment has been minimized.

Copy link
Member Author

commented Aug 20, 2013

But this is exactly what's happening on the current master branch when you try it on windows because there is no pattern check.

My question is still the same. What do you want to do if there is no result? Just returning false or empty array leads to the leaking info about files that are out of open_basedir.

However returning an empty array in any case except glob error would resolve the problem. Although it's an undocumented behaviour, it's small BC.

This discussion is about windows because pattern check works on Linux, so it's entirely up to you. If you don't think that it's a security risk, I can just hide pattern check for windows in this patch. The only problem is that the behaviour will be different on each platform.

@bukka

This comment has been minimized.

Copy link
Member Author

commented Aug 20, 2013

Just small correction. I know that this directories would be different on win.

The point of the example was just to show the logic. It would return an empty array for any non-existing files (even when you specify it without wildcard) and false for any existing file that is out of open basedir.

@pierrejoye

This comment has been minimized.

Copy link
Contributor

commented Aug 20, 2013

No result or open basedir restriction are two different things. That is
what we must double check.
On Aug 20, 2013 12:12 PM, "Jakub Zelenka" notifications@github.com wrote:

But this is exactly what's happening on the current master branch when you
try it on windows because there is no pattern check.

My question is still the same. What do you want to do if there is no
result? Just returning false or empty array leads to the leaking info about
files that are out of open_basedir.

However returning an empty array in any case except glob error would
resolve the problem. Although it's an undocumented behaviour, it's small BC.

This discussion is about windows because pattern check works on Linux, so
it's entirely up to you. If you don't think that it's a security risk, I
can just hide pattern check for windows in this patch. The only problem is
that the behaviour will be different on each platform.


Reply to this email directly or view it on GitHubhttps://github.com//pull/398#issuecomment-22934544
.

@bukka

This comment has been minimized.

Copy link
Member Author

commented Aug 20, 2013

Sorry I meant no result when there is an open basedir restriction. It means what to do if the open basedir is set and glob returns an empty result... :)

As I said I see two possible solutions:

  1. checking the pattern
  2. return an empty array in any case
    Maybe there is an another better way how to do that.

I just think that the current state needs to be changed.

@weltling

This comment has been minimized.

Copy link
Contributor

commented Aug 20, 2013

Well that's the dillema, there were two code paths

1
--query
----nomatch
------no basedir check possible on query
--------return [WHAT?]

2
--query
----match
------check basedir on concrete paths in loop
--------basedir ok -> return result array
--------basedir nok -> return [WHAT?]

That means to be consistent whatever [WHAT?] is returned in the 1st code path, the same in the 2nd should be returned. But that's not gonna work good, in the first code path there is no reliable way to check whether the query was in the basedir, like /[a,b,c]. Currently on linux it tries to check the query against basedir and that would work only if the query is a real path.

In case of returning false it'd break the case foreach(glob('nothing found') ... ) if it was nomatch. In case of empty array it'll not break it, but it'll not indicate the basepath error case. So that's a dillema (

@pierrejoye

This comment has been minimized.

Copy link
Contributor

commented Aug 20, 2013

If one single element falls because of obd, return false.
On Aug 20, 2013 1:10 PM, "Anatol Belski" notifications@github.com wrote:

Well that's the dillema, there were two code paths

1
--query
----nomatch
------no basedir check possible on query
--------return [WHAT?]

2
--query
----match
------check basedir on concrete paths in loop
--------basedir ok -> return result array
--------basedir nok -> return [WHAT?]

That means to be consistent whatever [WHAT?] is returned in the 1st code
path, the same in the 2nd should be returned. But that's not gonna work
good, in the first code path there is no reliable way to check whether the
query was in the basedir, like /[a,b,c]. Currently on linux it tries to
check the query against basedir and that would work only if the query is a
real path.

In case of returning false it'd break the case foreach(glob('nothing
found') ... ) if it was nomatch. In case of empty array it'll not break it,
but it'll not indicate the basepath error case. So that's a dillema (


Reply to this email directly or view it on GitHubhttps://github.com//pull/398#issuecomment-22937648
.

@weltling

This comment has been minimized.

Copy link
Contributor

commented Aug 20, 2013

Yep, that's exactly the question, as it's unknown in the 1st code path. You mean in that case false too?

@bukka

This comment has been minimized.

Copy link
Member Author

commented Aug 20, 2013

Do we really need to indicate that it's an open basedir restriction. If the reason for this is just to tell user that files have been filtered because there is an open basedir, then it doesn't cover all cases anyway.

Consider this:

dir structure

/var/www/test
/var/www/test/ok.txt
/var/www/hidden.txt

script:

<?php
ini_set('open_basedir', '/var/www')
glob('/var/www/*');

The return array contains only test but hidden.txt is not listed because of open basedir restriction.

The point is that in the case above you don't indicate that some files are hidden because of open basedir restriction. What's the point to indicate it in case that there are not any files found then?

@bukka

This comment has been minimized.

Copy link
Member Author

commented Aug 20, 2013

sorry the example in the previous comment contained few mistakes. I have just updated it so it should make sense now... :)

@weltling

This comment has been minimized.

Copy link
Contributor

commented Aug 21, 2013

I've filed a ticket about this https://bugs.php.net/bug.php?id=65489

@php-pulls

This comment has been minimized.

Copy link

commented Jan 1, 2017

Comment on behalf of krakjoe at php.net:

Since this PR contains merge conflicts, and since the author seems to have abandoned working on it, I'm closing this PR.

Please take this action as encouragement to work on the feature, open a clean PR, with satisfactory test coverage, and ensure those tests pass.

@php-pulls php-pulls closed this Jan 1, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.