summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Beaver <cellog@php.net>2008-05-11 21:15:47 +0000
committerGreg Beaver <cellog@php.net>2008-05-11 21:15:47 +0000
commit7149523766692c565fe81a12e358abe3d6fd4725 (patch)
tree9917e6ec6ab3dd83c0539eddaf79c899fedb814a
parent5d168ad5444cb73e13055e0a1b6d278146fb5b45 (diff)
downloadphp-git-7149523766692c565fe81a12e358abe3d6fd4725.tar.gz
add safety check to prevent unlinkArchive() from being called by a file within the archive
-rwxr-xr-xext/phar/phar_object.c18
-rw-r--r--ext/phar/tests/phar_unlinkarchive.phpt13
2 files changed, 29 insertions, 2 deletions
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index 08fd94d9ea..8c5bfb12cc 100755
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -1236,8 +1236,8 @@ PHP_METHOD(Phar, getSupportedCompression)
*/
PHP_METHOD(Phar, unlinkArchive)
{
- char *fname, *error;
- int fname_len;
+ char *fname, *error, *zname, *arch, *entry;
+ int fname_len, zname_len, arch_len, entry_len;
phar_archive_data *phar;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &fname, &fname_len) == FAILURE) {
@@ -1259,6 +1259,20 @@ PHP_METHOD(Phar, unlinkArchive)
return;
}
+ zname = zend_get_executed_filename(TSRMLS_C);
+ zname_len = strlen(zname);
+
+ if (zname_len > 7 && !memcmp(zname, "phar://", 7) && SUCCESS == phar_split_fname(zname, zname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
+ if (arch_len == fname_len && !memcmp(arch, fname, arch_len)) {
+ zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar archive \"%s\" cannot be unlinked from within itself", fname);
+ efree(arch);
+ efree(entry);
+ return;
+ }
+ efree(arch);
+ efree(entry);
+ }
+
if (phar->refcount) {
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar archive \"%s\" has open file handles or objects. fclose() all file handles, and unset() all objects prior to calling unlinkArchive()", fname);
return;
diff --git a/ext/phar/tests/phar_unlinkarchive.phpt b/ext/phar/tests/phar_unlinkarchive.phpt
index a239d54afb..910ef873d2 100644
--- a/ext/phar/tests/phar_unlinkarchive.phpt
+++ b/ext/phar/tests/phar_unlinkarchive.phpt
@@ -65,6 +65,16 @@ Phar::unlinkArchive($fname);
var_dump(file_exists($fname));
$phar = new Phar($fname);
var_dump(count($phar));
+$phar['evil.php'] = '<?php
+try {
+Phar::unlinkArchive(Phar::running(false));
+} catch (Exception $e) {echo $e->getMessage(),"\n";}
+var_dump(Phar::running(false));
+include Phar::running(true) . "/another.php";
+?>';
+$phar['another.php'] = "hi\n";
+unset($phar);
+include $pname . '/evil.php';
?>
===DONE===
--CLEAN--
@@ -92,4 +102,7 @@ string(60) "<?php // zip-based phar archive stub file
__HALT_COMPILER();"
bool(false)
int(0)
+phar archive "%sphar_unlinkarchive.phar" cannot be unlinked from within itself
+string(%d) "%sphar_unlinkarchive.phar"
+hi
===DONE===