Annotation of embedaddon/php/ext/phar/tests/tar/files/make.dangerous.tar.php.inc, revision 1.1.1.1

1.1       misho       1: <?php
                      2: // stolen from PEAR2_Pyrus_Developer_Creator_Tar by Greg Beaver, the original author, for use in unit tests
                      3: // this tarmaker makes a malicious tar with a header designed to overflow the buffer
                      4: class danger_tarmaker
                      5: {
                      6:     /**
                      7:      * Path to archive file
                      8:      *
                      9:      * @var string
                     10:      */
                     11:     protected $archive;
                     12:     /**
                     13:      * Temporary stream used for creating the archive
                     14:      *
                     15:      * @var stream
                     16:      */
                     17:     protected $tmp;
                     18:     protected $path;
                     19:     protected $compress;
                     20:     function __construct($path, $compress = 'zlib')
                     21:     {
                     22:         $this->compress = $compress;
                     23:         if ($compress === 'bz2' && !function_exists('bzopen')) {
                     24:             throw new PEAR2_Pyrus_Developer_Creator_Exception(
                     25:                 'bzip2 extension not available');
                     26:         }
                     27:         if ($compress === 'zlib' && !function_exists('gzopen')) {
                     28:             throw new PEAR2_Pyrus_Developer_Creator_Exception(
                     29:                 'zlib extension not available');
                     30:         }
                     31:         $this->path = $path;
                     32:     }
                     33: 
                     34:     /**
                     35:      * save a file inside this package
                     36:      * 
                     37:      * This code is modified from Vincent Lascaux's File_Archive
                     38:      * package, which is licensed under the LGPL license.
                     39:      * @param string relative path within the package
                     40:      * @param string|resource file contents or open file handle
                     41:      */
                     42:     function addFile($path, $fileOrStream, $stat = null)
                     43:     {
                     44:         clearstatcache();
                     45:         if ($stat === null) {
                     46:             if (is_resource($fileOrStream)) {
                     47:                 $stat = fstat($fileOrStream);
                     48:             } else {
                     49:                 $stat = array(
                     50:                     'mode' => 0x8000 + 0644,
                     51:                     'uid' => 0,
                     52:                     'gid' => 0,
                     53:                     'size' => strlen($fileOrStream),
                     54:                     'mtime' => time(),
                     55:                 );
                     56:             }
                     57:         }
                     58: 
                     59:         $link = null;
                     60:         if ($stat['mode'] & 0x4000) {
                     61:             $type = 5;        // Directory
                     62:         } else if ($stat['mode'] & 0x8000) {
                     63:             $type = 0;        // Regular
                     64:         } else if ($stat['mode'] & 0xA000) {
                     65:             $type = 1;        // Link
                     66:             $link = @readlink($current);
                     67:         } else {
                     68:             $type = 9;        // Unknown
                     69:         }
                     70: 
                     71:         $filePrefix = '';
                     72:         if (strlen($path) > 255) {
                     73:             throw new Exception(
                     74:                 "$path is too long, must be 255 characters or less"
                     75:             );
                     76:         } else if (strlen($path) > 100) {
                     77:             $filePrefix = substr($path, 0, strlen($path)-100);
                     78:             $path = substr($path, -100);
                     79:         }
                     80: 
                     81:         $block = pack('a100a8a8a8a12A12',
                     82:                 $path,
                     83:                 '12345678', // have a mode that allows the name to overflow
                     84:                 sprintf('%6s ',decoct($stat['uid'])),
                     85:                 sprintf('%6s ',decoct($stat['gid'])),
                     86:                 sprintf('%11s ',decoct($stat['size'])),
                     87:                 sprintf('%11s ',decoct($stat['mtime']))
                     88:             );
                     89: 
                     90:         $blockend = pack('a1a100a6a2a32a32a8a8a155a12',
                     91:             $type,
                     92:             $link,
                     93:             'ustar',
                     94:             '00',
                     95:             'Pyrus',
                     96:             'Pyrus',
                     97:             '',
                     98:             '',
                     99:             $filePrefix,
                    100:             '123456789abc'); // malicious block
                    101: 
                    102:         $checkheader = array_merge(str_split($block), str_split($blockend));
                    103:         if (!function_exists('_pear2tarchecksum')) {
                    104:             function _pear2tarchecksum($a, $b) {return $a + ord($b);}
                    105:         }
                    106:         $checksum = 256; // 8 * ord(' ');
                    107:         $checksum += array_reduce($checkheader, '_pear2tarchecksum');
                    108: 
                    109:         $checksum = pack('a8', sprintf('%6s ', decoct($checksum)));
                    110: 
                    111:         fwrite($this->tmp, (binary)$block . $checksum . $blockend, 512);
                    112:         if (is_resource($fileOrStream)) {
                    113:             stream_copy_to_stream($fileOrStream, $this->tmp);
                    114:             if ($stat['size'] % 512) {
                    115:                 fwrite($this->tmp, (binary)str_repeat("\0", 512 - $stat['size'] % 512));
                    116:             }
                    117:         } else {
                    118:             fwrite($this->tmp, (binary)$fileOrStream);
                    119:             if (strlen($fileOrStream) % 512) {
                    120:                 fwrite($this->tmp, (binary)str_repeat("\0", 512 - strlen($fileOrStream) % 512));
                    121:             }
                    122:         }
                    123:     }
                    124: 
                    125:     /**
                    126:      * Initialize the package creator
                    127:      */
                    128:     function init()
                    129:     {
                    130:         switch ($this->compress) {
                    131:             case 'zlib' :
                    132:                 $this->tmp = gzopen($this->path, 'wb');
                    133:                 break;
                    134:             case 'bz2' :
                    135:                 $this->tmp = bzopen($this->path, 'w');
                    136:                 break;
                    137:             case 'none' :
                    138:                 $this->tmp = fopen($this->path, 'wb');
                    139:                 break;
                    140:             default :
                    141:                 throw new Exception(
                    142:                     'unknown compression type ' . $this->compress);
                    143:         }
                    144:     }
                    145: 
                    146:     /**
                    147:      * Create an internal directory, creating parent directories as needed
                    148:      * 
                    149:      * @param string $dir
                    150:      */
                    151:     function mkdir($dir)
                    152:     {
                    153:         $this->addFile($dir, "", array(
                    154:                     'mode' => 0x4000 + 0644,
                    155:                     'uid' => 0,
                    156:                     'gid' => 0,
                    157:                     'size' => 0,
                    158:                     'mtime' => time(),
                    159:                 ));
                    160:     }
                    161: 
                    162:     /**
                    163:      * Finish saving the package
                    164:      */
                    165:     function close()
                    166:     {
                    167:         fwrite($this->tmp, pack('a1024', ''));
                    168:         fclose($this->tmp);
                    169:     }
                    170: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>