]> granicus.if.org Git - php/commitdiff
add safety check to prevent unlinkArchive() from being called by a file within the...
authorGreg Beaver <cellog@php.net>
Sun, 11 May 2008 21:15:47 +0000 (21:15 +0000)
committerGreg Beaver <cellog@php.net>
Sun, 11 May 2008 21:15:47 +0000 (21:15 +0000)
ext/phar/phar_object.c
ext/phar/tests/phar_unlinkarchive.phpt

index 08fd94d9ea261dc3c88ce957b42d15a79619e7ef..8c5bfb12cc50e98ba594ed1afbacc4d61dcc46a5 100755 (executable)
@@ -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;
index a239d54afbcc2f60bc9df1cd33f52f2c45792500..910ef873d2d58ce94bd6da9a0e3b24ec0693947e 100644 (file)
@@ -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===