diff options
author | Greg Beaver <cellog@php.net> | 2008-05-11 21:15:47 +0000 |
---|---|---|
committer | Greg Beaver <cellog@php.net> | 2008-05-11 21:15:47 +0000 |
commit | 7149523766692c565fe81a12e358abe3d6fd4725 (patch) | |
tree | 9917e6ec6ab3dd83c0539eddaf79c899fedb814a | |
parent | 5d168ad5444cb73e13055e0a1b6d278146fb5b45 (diff) | |
download | php-git-7149523766692c565fe81a12e358abe3d6fd4725.tar.gz |
add safety check to prevent unlinkArchive() from being called by a file within the archive
-rwxr-xr-x | ext/phar/phar_object.c | 18 | ||||
-rw-r--r-- | ext/phar/tests/phar_unlinkarchive.phpt | 13 |
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=== |