-
Notifications
You must be signed in to change notification settings - Fork 7.8k
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 GH-10755: Memory leak in phar_rename_archive() #10856
Conversation
stkeke
commented
Mar 15, 2023
In phar_renmae_archive() context, added one reference but immediately destroyed another, so do not need to increase refcount. With removal of refcount++ line, PHP/Zend no longer reports memory leak. Updated bug69958.phpt test file accordingly. Testing (PASS on both Debug and Release build) Debug: ./configure --enable-debug Release: ./configure 1) Running selected tests. PASS Phar: bug #69958: Segfault in Phar::convertToData on invalid file [bug69958.phpt] 2) All tests under ext/phar/tests PASSED except skipped. ===================================================================== Number of tests : 530 515 Tests skipped : 15 ( 2.8%) -------- Tests warned : 0 ( 0.0%) ( 0.0%) Tests failed : 0 ( 0.0%) ( 0.0%) Tests passed : 515 ( 97.2%) (100.0%) --------------------------------------------------------------------- Time taken : 26 seconds ===================================================================== Signed-off-by: Su, Tao <[email protected]>
According to Niels Dossche, remove slash character (/) in bug69958.php test file in order to support testing on both Linux and Windows. Link: #10848 Signed-off-by: Tony Su <[email protected]>
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.
ASAN reveals an incorrect free here for phar->alias. Duplicating apparently causes leaks in other places. I don't really know the solution. Do you want to take a closer look or should I?
@iluuu1994 If you can take a closer look, that would be wonderful. |
@stkeke Did you also pass the |
@iluuu1994 I now can reproduce and debug this issue with --asan flag. Thanks for instructing. |
This is what I got today... @nielsdos told me pemalloc/pefree should be paired.
|
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index ba47cd8843..fbf454e499 100644
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -2113,10 +2113,12 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /*
pphar->flags = phar->flags;
pphar->fp = phar->fp;
phar->fp = NULL;
+ phar->alias = NULL;
phar_destroy_phar_data(phar);
*sphar = NULL;
phar = pphar;
- phar->refcount++;
+ /* FIX: GH-10755 Memory leak in phar_rename_archive() */
+ /* phar->refcount++; */
newpath = oldpath;
goto its_ok;
} I think this might do it. Setting |
@iluuu1994 Thanks for the hint. Let me check and test it tomorrow. |
@iluuu1994 I still need one more day to understand the code logic Only one thing I am not sure, someone (include me) might have a concern that I am wondering, could we do? pphar->fp = phar->fp;
phar->fp = NULL;
+ pphar->alias = phar->alias; /* transfer alias to pphar just as fp */
+ phar->alias = NULL; /* fix double-free issue caught by ASAN */ |
@stkeke Of course, sorry, that line was missing in my example. I really don't know how this code works (I've looked at it only superficially) but from looking at how the other properties are handled here that seems to make sense. |
@iluuu1994 I traced the So your fixation is quite correct. Let's use it to avoid the first-time release and let it go in destructor. How
|
After having fixed memory leak, ASAN check reported double-free of phar->alias (char*) string. We found the root cause and documented it at #10856 Solution is provided by Ilija Tovilo (iluuu1994). Signed-off-by: Tony Su <[email protected]> Reviewed-by: Ilija Tovilo Tested-by: Tony Su <[email protected]>
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.
Thank you @stkeke! Since I'm not familiar with phar at all (but also few people left seem to be) I'd be more comfortable merging this into master. A leak is better than memory corruption. Does that work for you?
phar_destroy_phar_data(phar); | ||
*sphar = NULL; | ||
phar = pphar; | ||
phar->refcount++; | ||
/* FIX: GH-10755 Memory leak in phar_rename_archive() */ | ||
/* phar->refcount++; */ |
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.
Just remove the code.
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.
Sure, no problem. You can simple change it.