|
22 | 22 |
|
23 | 23 | #include "ext/standard/md5.h"
|
24 | 24 | #include "zend_virtual_cwd.h"
|
| 25 | +#include "main/php_open_temporary_file.h" |
25 | 26 |
|
26 | 27 | #include <sys/types.h>
|
27 | 28 | #include <sys/stat.h>
|
@@ -2119,7 +2120,10 @@ static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr s
|
2119 | 2120 | HashTable tmp_bindings;
|
2120 | 2121 | HashTable tmp_functions;
|
2121 | 2122 |
|
2122 |
| - f = open(fn,O_CREAT|O_WRONLY|O_EXCL|O_BINARY,S_IREAD|S_IWRITE); |
| 2123 | + /* To avoid race conditions, we first create a temporary file and then rename it atomically |
| 2124 | + * at the end of the function. (see bug #66150) */ |
| 2125 | + zend_string *temp_file_path; |
| 2126 | + f = php_open_temporary_fd_ex(SOAP_GLOBAL(cache_dir), "tmp.wsdl.", &temp_file_path, PHP_TMP_FILE_SILENT); |
2123 | 2127 |
|
2124 | 2128 | if (f < 0) {return;}
|
2125 | 2129 |
|
@@ -2371,13 +2375,21 @@ static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr s
|
2371 | 2375 | } ZEND_HASH_FOREACH_END();
|
2372 | 2376 | }
|
2373 | 2377 |
|
2374 |
| - php_ignore_value(write(f, ZSTR_VAL(buf.s), ZSTR_LEN(buf.s))); |
| 2378 | + bool valid_file = write(f, ZSTR_VAL(buf.s), ZSTR_LEN(buf.s)) == ZSTR_LEN(buf.s); |
2375 | 2379 | close(f);
|
| 2380 | + |
| 2381 | + /* Make sure that incomplete files (e.g. due to disk space issues, see bug #66150) are not utilised. */ |
| 2382 | + if (valid_file) { |
| 2383 | + /* This is allowed to fail, this means that another process was raced to create the file. */ |
| 2384 | + (void) VCWD_RENAME(ZSTR_VAL(temp_file_path), fn); |
| 2385 | + } |
| 2386 | + |
2376 | 2387 | smart_str_free(&buf);
|
2377 | 2388 | zend_hash_destroy(&tmp_functions);
|
2378 | 2389 | zend_hash_destroy(&tmp_bindings);
|
2379 | 2390 | zend_hash_destroy(&tmp_encoders);
|
2380 | 2391 | zend_hash_destroy(&tmp_types);
|
| 2392 | + zend_string_release_ex(temp_file_path, false); |
2381 | 2393 | }
|
2382 | 2394 |
|
2383 | 2395 |
|
|
0 commit comments