15
15
*/
16
16
17
17
#include "php.h"
18
+ #include "zend_long.h"
18
19
#include "php_open_temporary_file.h"
20
+ #include "ext/random/php_random.h"
19
21
20
22
#include <errno.h>
21
23
#include <sys/types.h>
@@ -89,11 +91,13 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, zend_st
89
91
#ifdef PHP_WIN32
90
92
char * opened_path = NULL ;
91
93
size_t opened_path_len ;
92
- wchar_t * cwdw , * pfxw , pathw [MAXPATHLEN ];
94
+ wchar_t * cwdw , * random_prefix_w , pathw [MAXPATHLEN ];
93
95
#else
94
96
char opened_path [MAXPATHLEN ];
95
97
char * trailing_slash ;
96
98
#endif
99
+ uint64_t random [2 ];
100
+ char * random_prefix ;
97
101
char cwd [MAXPATHLEN ];
98
102
cwd_state new_state ;
99
103
int fd = -1 ;
@@ -128,34 +132,45 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, zend_st
128
132
return -1 ;
129
133
}
130
134
135
+ /* Extend the prefix to increase randomness */
136
+ if (php_random_bytes_silent (& random , sizeof (random )) == FAILURE ) {
137
+ random [0 ] = php_random_generate_fallback_seed ();
138
+ random [1 ] = php_random_generate_fallback_seed ();
139
+ }
140
+
141
+ spprintf (& random_prefix , 0 , "%s%016" PRIx64 "%016" PRIx64 , pfx , random [0 ], random [1 ]);
142
+
131
143
#ifndef PHP_WIN32
132
144
if (IS_SLASH (new_state .cwd [new_state .cwd_length - 1 ])) {
133
145
trailing_slash = "" ;
134
146
} else {
135
147
trailing_slash = "/" ;
136
148
}
137
149
138
- if (snprintf (opened_path , MAXPATHLEN , "%s%s%sXXXXXX" , new_state .cwd , trailing_slash , pfx ) >= MAXPATHLEN ) {
150
+ if (snprintf (opened_path , MAXPATHLEN , "%s%s%sXXXXXX" , new_state .cwd , trailing_slash , random_prefix ) >= MAXPATHLEN ) {
151
+ efree (random_prefix );
139
152
efree (new_state .cwd );
140
153
return -1 ;
141
154
}
142
155
#endif
143
156
144
157
#ifdef PHP_WIN32
145
158
cwdw = php_win32_ioutil_any_to_w (new_state .cwd );
146
- pfxw = php_win32_ioutil_any_to_w (pfx );
147
- if (!cwdw || !pfxw ) {
159
+ random_prefix_w = php_win32_ioutil_any_to_w (random_prefix );
160
+ if (!cwdw || !random_prefix_w ) {
148
161
free (cwdw );
149
- free (pfxw );
162
+ free (random_prefix_w );
163
+ efree (random_prefix );
150
164
efree (new_state .cwd );
151
165
return -1 ;
152
166
}
153
167
154
- if (GetTempFileNameW (cwdw , pfxw , 0 , pathw )) {
168
+ if (GetTempFileNameW (cwdw , random_prefix_w , 0 , pathw )) {
155
169
opened_path = php_win32_ioutil_conv_w_to_any (pathw , PHP_WIN32_CP_IGNORE_LEN , & opened_path_len );
156
170
if (!opened_path || opened_path_len >= MAXPATHLEN ) {
157
171
free (cwdw );
158
- free (pfxw );
172
+ free (random_prefix_w );
173
+ efree (random_prefix );
159
174
efree (new_state .cwd );
160
175
return -1 ;
161
176
}
@@ -165,7 +180,8 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, zend_st
165
180
* which means that opening it will fail... */
166
181
if (VCWD_CHMOD (opened_path , 0600 )) {
167
182
free (cwdw );
168
- free (pfxw );
183
+ free (random_prefix_w );
184
+ efree (random_prefix );
169
185
efree (new_state .cwd );
170
186
free (opened_path );
171
187
return -1 ;
@@ -174,7 +190,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, zend_st
174
190
}
175
191
176
192
free (cwdw );
177
- free (pfxw );
193
+ free (random_prefix_w );
178
194
#elif defined(HAVE_MKSTEMP )
179
195
fd = mkstemp (opened_path );
180
196
#else
@@ -194,6 +210,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, zend_st
194
210
}
195
211
#endif
196
212
efree (new_state .cwd );
213
+ efree (random_prefix );
197
214
return fd ;
198
215
}
199
216
/* }}} */
0 commit comments