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>