-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix stream double free in phar #18953
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
base: master
Are you sure you want to change the base?
Conversation
517e8ad
to
5b94a74
Compare
// cleaning | ||
@unlink("gh18953.phar"); | ||
@unlink("gh18953.phar.gz"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be needed because of the CLEAN section
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If last test failed without cleaning, this test will never success. So I unlink them here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A CLEAN section always runs, if it doesn't there are bigger problems with the test runner. Please remove it as asked previously.
spl_autoload_register(function ($class) { | ||
$base_dir = __DIR__ . '/src/'; | ||
|
||
$file = $base_dir . str_replace('\\', '/', $class) . '.inc'; | ||
if (file_exists($file)) { | ||
require $file; | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you not move this into the base test file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure require
matters, so I splited them
@@ -2306,6 +2306,13 @@ static zend_object *phar_convert_to_other(phar_archive_data *source, int convert | |||
/* exception already thrown */ | |||
return NULL; | |||
} | |||
|
|||
if (newentry.fp == NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like the wrong solution. You're resetting the file pointer but phar_copy_file_contents
already used it.
I believe the right solution is to:
- Reset fp and cfp right after the copy from entry to newentry. The new file pointer will then be opened and set correctly in
phar_copy_file_contents
- Remove the
/* save for potential restore on error */
block that moves the file pointers as this recovery mechanism isn't implemented as far as I see.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's hard for me to understand why phar codes use cfp
, so I use this strange solution to avoid break other features.
Also, there are many memcpys (like newentry <- entry here), dont know why, so I chose to not modify phar_copy_file_contents
--INI-- | ||
phar.readonly=0 | ||
--ENV-- | ||
USE_ZEND_ALLOC=0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
phar.readonly=0
is needed, as for USE_ZEND_ALLOC=0, it helps reproducing in common php test environment (without ASAN)
|
||
declare(strict_types=1); | ||
|
||
require __DIR__ . '/gh18953/autoload.inc'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need all this autoloading stuff, nor the classes at the bottom. Executing the test without these things, with ASAN+USE_ZEND_ALLOC=0, reliably reproduces the bug.
Ths PR is more like a bug report rather than a bug fix. It's so hard for someone like me to read the entire phar code and make real good fixes, this is a patch only managing to work for my own project. I'm eager to work on my own project. If |
I wont modify this PR because it's really not a good fix (and should not be merged/fixed in this way), and wait for better fixes. |
I've encountered a bug that simply this code can trigger:
With zendmm. Codes below increases reproduce chance
It's a UAF/double free, but it's with very little probability because of zendmm / memory allocater.
With help of ASan, this can be triggered every time.
I used a straightforward way to fix it, but it's hard to write a test file to check this with zendmm