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
+ zend_long random ;
100
+ char * random_prefix ;
97
101
char cwd [MAXPATHLEN ];
98
102
cwd_state new_state ;
99
103
int fd = -1 ;
@@ -128,34 +132,60 @@ 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 randoness */
136
+ if (php_random_int (ZEND_LONG_MIN , ZEND_LONG_MAX , & random , /* should_throw */ false) == FAILURE ) {
137
+ /* Fallback to non-csprng */
138
+ uint64_t t [4 ];
139
+ php_random_status_state_xoshiro256starstar state ;
140
+ do {
141
+ t [0 ] = php_random_generate_fallback_seed ();
142
+ t [1 ] = php_random_generate_fallback_seed ();
143
+ t [2 ] = php_random_generate_fallback_seed ();
144
+ t [3 ] = php_random_generate_fallback_seed ();
145
+ } while (UNEXPECTED (t [0 ] == 0 && t [1 ] == 0 && t [2 ] == 0 && t [3 ] == 0 ));
146
+
147
+ php_random_xoshiro256starstar_seed256 (& state , t [0 ], t [1 ], t [2 ], t [3 ]);
148
+ php_random_result result = php_random_algo_xoshiro256starstar .generate (& state );
149
+ random = (zend_long ) result .result ;
150
+ }
151
+
152
+ if (spprintf (& random_prefix , MAXPATHLEN , "%s" ZEND_XLONG_FMT , pfx , random ) >= MAXPATHLEN ) {
153
+ efree (random_prefix );
154
+ efree (new_state .cwd );
155
+ return -1 ;
156
+ }
157
+
131
158
#ifndef PHP_WIN32
132
159
if (IS_SLASH (new_state .cwd [new_state .cwd_length - 1 ])) {
133
160
trailing_slash = "" ;
134
161
} else {
135
162
trailing_slash = "/" ;
136
163
}
137
164
138
- if (snprintf (opened_path , MAXPATHLEN , "%s%s%sXXXXXX" , new_state .cwd , trailing_slash , pfx ) >= MAXPATHLEN ) {
165
+ if (snprintf (opened_path , MAXPATHLEN , "%s%s%sXXXXXX" , new_state .cwd , trailing_slash , random_prefix ) >= MAXPATHLEN ) {
166
+ efree (random_prefix );
139
167
efree (new_state .cwd );
140
168
return -1 ;
141
169
}
142
170
#endif
143
171
144
172
#ifdef PHP_WIN32
145
173
cwdw = php_win32_ioutil_any_to_w (new_state .cwd );
146
- pfxw = php_win32_ioutil_any_to_w (pfx );
147
- if (!cwdw || !pfxw ) {
174
+ random_prefix_w = php_win32_ioutil_any_to_w (random_prefix );
175
+ if (!cwdw || !random_prefix_w ) {
148
176
free (cwdw );
149
- free (pfxw );
177
+ free (random_prefix_w );
178
+ efree (random_prefix );
150
179
efree (new_state .cwd );
151
180
return -1 ;
152
181
}
153
182
154
- if (GetTempFileNameW (cwdw , pfxw , 0 , pathw )) {
183
+ if (GetTempFileNameW (cwdw , random_prefix_w , 0 , pathw )) {
155
184
opened_path = php_win32_ioutil_conv_w_to_any (pathw , PHP_WIN32_CP_IGNORE_LEN , & opened_path_len );
156
185
if (!opened_path || opened_path_len >= MAXPATHLEN ) {
157
186
free (cwdw );
158
- free (pfxw );
187
+ free (random_prefix_w );
188
+ efree (random_prefix );
159
189
efree (new_state .cwd );
160
190
return -1 ;
161
191
}
@@ -165,7 +195,8 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, zend_st
165
195
* which means that opening it will fail... */
166
196
if (VCWD_CHMOD (opened_path , 0600 )) {
167
197
free (cwdw );
168
- free (pfxw );
198
+ free (random_prefix_w );
199
+ efree (random_prefix );
169
200
efree (new_state .cwd );
170
201
free (opened_path );
171
202
return -1 ;
@@ -174,7 +205,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, zend_st
174
205
}
175
206
176
207
free (cwdw );
177
- free (pfxw );
208
+ free (random_prefix_w );
178
209
#elif defined(HAVE_MKSTEMP )
179
210
fd = mkstemp (opened_path );
180
211
#else
@@ -194,6 +225,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, zend_st
194
225
}
195
226
#endif
196
227
efree (new_state .cwd );
228
+ efree (random_prefix );
197
229
return fd ;
198
230
}
199
231
/* }}} */
0 commit comments