Uh oh!
There was an error while loading. Please reload this page.
Fix bug #40531 mb_substr optional parameters - #13
Conversation
zend_verify_arg_type() only accepted to verify arg types as classes, arrays or objects. Now it accepts integers. This is necessary to check wether an argument is an integer or null, which can't be done at a higher level like zend_parse_parameters(...,"l").
To distinguish between null and 0 for an integer parameter, we have to use the "z!" type instead of "l" in zend_parse_parameters(). So the type checks are now done in the prototype with ZEND_ARG_TYPE_INFO(). The prototype is more strict than before. An non integer (or a string that isn't purely numeric) will lead to a fatal error, whereas there was previously a simple warning.
nikic
commented
Mar 20, 2012
This seems like a rather strange way to fix the issue. Changing the Zend Engine should not be required. What would be the problem with fetching the value as |
mytskine
commented
Mar 20, 2012
I first did like you suggested. But then there is no parameter validation in This is my first look at PHP's code, so of course I may be completly wrong. |
mytskine
commented
Mar 20, 2012
Le 2012-03-20, nikic
I've just seen that my second commit re-introduces something that was removed It seems my proposed patch has just landed in the hot topic of scalar type |
smalyshev
commented
Mar 20, 2012
I don't think changes to how the engine handles arguments can be introduced without RFC and discussion. |
php-pulls
commented
Mar 20, 2012
Comment on behalf of johannes at php.net: test (please ignore) |
ircmaxell
commented
Mar 20, 2012
This actually has a direct impact on the scalar type hinting discussion as it actually implements the type-hints differently for the core functions which as-of-yet is not supported... Why not just change the arg type in zend_parse_parameters to expect an int in that case (like every other core function)...? Anthony |
cataphract
commented
Mar 20, 2012
As you can't use the For instance, I have this still uncommitted code for the intl extension: |
mytskine
commented
Mar 20, 2012
A few comments about ctaphract's suggestion:
More globally, here are my "naïve" thoughts:
Finally, I believe I should have posted in the internals list instead of |
php-pulls
commented
Mar 20, 2012
Hi!
I think it's because there never was a use case for it. You actually Right now I don't see a clean way to return null in 'l' field from
zend_parse_parameters() does define type, but type "long or null" is not Stanislav Malyshev, Software Architect |
mytskine
commented
Mar 21, 2012
Thanks for this reply. I'm glad to know there are plans for a better way to deal with optional arguments. I still think that the type checks for the arguments of internal functions are too limited. Maybe type checks shouldn't be added to I'm closing this pull request. I may submit another one with my own parsing and validation and error messages for "long or null" arguments, but I'll probably wait for changes in the API that would avoid this. Thanks to everyone here for the valuable experience. |
cataphract
commented
Mar 21, 2012
I meant In any case, you won't need to add your own error messages or type validations. I should have stripped those from my example because the intl extension actually has its own error handling mechanism. The only exception is that you have to validate the number of arguments if you use In the long term, adding a modifier similar to |
smalyshev
commented
Mar 23, 2012
I would rather do it differently - I'd allow to run parse on a single parameter, i.e. have initial parse with 'z' and then depending on some code have something like: zend_parse_single_arg(my_arg, "l", &l) So you could do your own checks and then still benefit from the clean API provided by parameter parser. |
a traditional property declaration. Also added XFAIL sections to a few tests that are expected to fail for now until other tickets are closed. fixesphp#13
The following opcodes would be generated:
...
BB1:
0003 JMP BB3
BB2:
0004 INIT_FCALL 1 96 string("chr")
0005 #10.T3 [long] = SR #3.CV0($int) [long] #7.CV2($i) ...
0006 #11.T4 [long] RANGE[0..127] = BW_AND #10.T3 [long] ...
0007 #12.T3 [long] RANGE[128..255] = BW_OR #11.T4 [long] ...
0008 SEND_VAL #12.T3 [long] RANGE[128..255] 1
0009 #13.V3 [ref, rc1, rcn, any] = DO_ICALL
0010 ASSIGN_OP (CONCAT) #6.CV1($out) [rc1, rcn, string]
0011 ADD #7.CV2($i)... int(7) #7.CV2($i) ... -> #15.CV2($i) ...
BB3:
0012 #8.T4 [long] = SR #3.CV0($int) #7.CV2($i) [long, double]
0013 #9.T3 [bool] RANGE[0..1] = IS_SMALLER int(128) #8.T4
0014 JMPNZ #9.T3 [bool] RANGE[0..1] BB2
...
Main changes are:
1. SR opcode covers new path in function zend_jit_long_math_helper().
2. BW_AND and BW_OR opcodes are supported. See macro LONG_OP.
3. Function zend_jit_concat_helper() is added to support ASSIGN_OP
opcode. Speficically, CONCAT and FAST_CONCAT is supported for statements
"$out .= ...".
4. New path is covered in function zend_jit_cmp_long_long() by
IS_SMALLER opcode.
5. New path is covered in macros ZVAL_PTR_DTOR and ZVAL_DTOR_FUNC when
leaving.The following opcodes would be generated:
...
BB1:
0003 JMP BB3
BB2:
0004 INIT_FCALL 1 96 string("chr")
0005 #10.T3 [long] = SR #3.CV0($int) [long] #7.CV2($i) ...
0006 #11.T4 [long] RANGE[0..127] = BW_AND #10.T3 [long] ...
0007 #12.T3 [long] RANGE[128..255] = BW_OR #11.T4 [long] ...
0008 SEND_VAL #12.T3 [long] RANGE[128..255] 1
0009 #13.V3 [ref, rc1, rcn, any] = DO_ICALL
0010 ASSIGN_OP (CONCAT) #6.CV1($out) [rc1, rcn, string]
0011 ADD #7.CV2($i)... int(7) #7.CV2($i) ... -> #15.CV2($i) ...
BB3:
0012 #8.T4 [long] = SR #3.CV0($int) #7.CV2($i) [long, double]
0013 #9.T3 [bool] RANGE[0..1] = IS_SMALLER int(128) #8.T4
0014 JMPNZ #9.T3 [bool] RANGE[0..1] BB2
...
Main changes are:
1. SR opcode covers new path in function zend_jit_long_math_helper().
2. BW_AND and BW_OR opcodes are supported. See macro LONG_OP.
3. Function zend_jit_concat_helper() is added to support ASSIGN_OP
opcode. Speficically, CONCAT and FAST_CONCAT is supported for statements
"$out .= ...".
4. New path is covered in function zend_jit_cmp_long_long() by
IS_SMALLER opcode.
5. New path is covered in macros ZVAL_PTR_DTOR and ZVAL_DTOR_FUNC when
leaving.The following opcodes would be generated:
...
BB1:
0003 JMP BB3
BB2:
0004 INIT_FCALL 1 96 string("chr")
0005 #10.T3 [long] = SR #3.CV0($int) [long] #7.CV2($i) ...
0006 #11.T4 [long] RANGE[0..127] = BW_AND #10.T3 [long] ...
0007 #12.T3 [long] RANGE[128..255] = BW_OR #11.T4 [long] ...
0008 SEND_VAL #12.T3 [long] RANGE[128..255] 1
0009 #13.V3 [ref, rc1, rcn, any] = DO_ICALL
0010 ASSIGN_OP (CONCAT) #6.CV1($out) [rc1, rcn, string]
0011 ADD #7.CV2($i)... int(7) #7.CV2($i) ... -> #15.CV2($i) ...
BB3:
0012 #8.T4 [long] = SR #3.CV0($int) #7.CV2($i) [long, double]
0013 #9.T3 [bool] RANGE[0..1] = IS_SMALLER int(128) #8.T4
0014 JMPNZ #9.T3 [bool] RANGE[0..1] BB2
...
Main changes are:
1. SR opcode covers new path in function zend_jit_long_math_helper().
2. BW_AND and BW_OR opcodes are supported. See macro LONG_OP.
3. Function zend_jit_concat_helper() is added to support ASSIGN_OP
opcode. Speficically, CONCAT and FAST_CONCAT is supported for statements
"$out .= ...".
4. New path is covered in function zend_jit_cmp_long_long() by
IS_SMALLER opcode.
5. New path is covered in macros ZVAL_PTR_DTOR and ZVAL_DTOR_FUNC when
leaving.The following opcodes would be generated:
...
BB1:
0003 JMP BB3
BB2:
0004 INIT_FCALL 1 96 string("chr")
0005 #10.T3 [long] = SR #3.CV0($int) [long] #7.CV2($i) ...
0006 #11.T4 [long] RANGE[0..127] = BW_AND #10.T3 [long] ...
0007 #12.T3 [long] RANGE[128..255] = BW_OR #11.T4 [long] ...
0008 SEND_VAL #12.T3 [long] RANGE[128..255] 1
0009 #13.V3 [ref, rc1, rcn, any] = DO_ICALL
0010 ASSIGN_OP (CONCAT) #6.CV1($out) [rc1, rcn, string]
0011 ADD #7.CV2($i)... int(7) #7.CV2($i) ... -> #15.CV2($i) ...
BB3:
0012 #8.T4 [long] = SR #3.CV0($int) #7.CV2($i) [long, double]
0013 #9.T3 [bool] RANGE[0..1] = IS_SMALLER int(128) #8.T4
0014 JMPNZ #9.T3 [bool] RANGE[0..1] BB2
...
Main changes are:
1. SR opcode covers new path in function zend_jit_long_math_helper().
2. BW_AND and BW_OR opcodes are supported. See macro LONG_OP.
3. Function zend_jit_concat_helper() is added to support ASSIGN_OP
opcode. Speficically, CONCAT and FAST_CONCAT is supported for statements
"$out .= ...".
4. New path is covered in function zend_jit_cmp_long_long() by
IS_SMALLER opcode.
5. New path is covered in macros ZVAL_PTR_DTOR and ZVAL_DTOR_FUNC when
leaving.The following opcodes would be generated:
...
BB1:
0003 JMP BB3
BB2:
0004 INIT_FCALL 1 96 string("chr")
0005 #10.T3 [long] = SR #3.CV0($int) [long] #7.CV2($i) ...
0006 #11.T4 [long] RANGE[0..127] = BW_AND #10.T3 [long] ...
0007 #12.T3 [long] RANGE[128..255] = BW_OR #11.T4 [long] ...
0008 SEND_VAL #12.T3 [long] RANGE[128..255] 1
0009 #13.V3 [ref, rc1, rcn, any] = DO_ICALL
0010 ASSIGN_OP (CONCAT) #6.CV1($out) [rc1, rcn, string]
0011 ADD #7.CV2($i)... int(7) #7.CV2($i) ... -> #15.CV2($i) ...
BB3:
0012 #8.T4 [long] = SR #3.CV0($int) #7.CV2($i) [long, double]
0013 #9.T3 [bool] RANGE[0..1] = IS_SMALLER int(128) #8.T4
0014 JMPNZ #9.T3 [bool] RANGE[0..1] BB2
...
Main changes are:
1. SR opcode covers new path in function zend_jit_long_math_helper().
2. BW_AND and BW_OR opcodes are supported. See macro LONG_OP.
3. Function zend_jit_concat_helper() is added to support ASSIGN_OP
opcode. Speficically, CONCAT and FAST_CONCAT is supported for statements
"$out .= ...".
4. New path is covered in function zend_jit_cmp_long_long() by
IS_SMALLER opcode.
5. New path is covered in macros ZVAL_PTR_DTOR and ZVAL_DTOR_FUNC when
leaving.This is observable in LibreSSL. The code is creating 3 big numbers, but if one of them failed to create, then DSA_set0_pqg() will have never executed and there are no references left to the created big numbers, leaking them in the process. E.g.: ``` Direct leak of 24 byte(s) in 1 object(s) allocated from: #0 0x7f4edd402340 in calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77 #1 0x7f4edce9d106 in BN_new bn/bn_lib.c:75 #2 0x7f4edce9706c in bn_bin2bn_cbs bn/bn_convert.c:151 #3 0x7f4edce97853 in BN_bin2bn bn/bn_convert.c:206 #4 0x5556bd923e1d in php_openssl_pkey_init_dsa_data /work/php-src/ext/openssl/openssl_backend_v1.c:142 #5 0x5556bd92428f in php_openssl_pkey_init_dsa /work/php-src/ext/openssl/openssl_backend_v1.c:186 #6 0x5556bd8fe079 in zif_openssl_pkey_new /work/php-src/ext/openssl/openssl.c:2042 #7 0x5556be6b44e5 in zend_test_execute_internal /work/php-src/ext/zend_test/observer.c:306 #8 0x5556be9dc85a in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER /work/php-src/Zend/zend_vm_execute.h:2154 #9 0x5556beb3cfa5 in execute_ex /work/php-src/Zend/zend_vm_execute.h:116519 #10 0x5556beb51ec0 in zend_execute /work/php-src/Zend/zend_vm_execute.h:121962 #11 0x5556becb60cc in zend_execute_script /work/php-src/Zend/zend.c:1980 #12 0x5556be6e8ecb in php_execute_script_ex /work/php-src/main/main.c:2645 #13 0x5556be6e92db in php_execute_script /work/php-src/main/main.c:2685 #14 0x5556becbbc37 in do_cli /work/php-src/sapi/cli/php_cli.c:951 #15 0x5556becbe204 in main /work/php-src/sapi/cli/php_cli.c:1362 #16 0x7f4edca671c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #17 0x7f4edca6728a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #18 0x5556bd809db4 in _start (/work/php-src/build-dbg-asan/sapi/cli/php+0x609db4) (BuildId: 5cc444a6a9fc1a486ea698e72366c16bd5472605) ``` ClosesGH-21062.
This causes UB later on when the certificate is passed to another function: ``` /work/php-src/Zend/zend_string.h:191:2: runtime error: null pointer passed as argument 2, which is declared to never be null #0 0x55cfb9407d94 in zend_string_init /work/php-src/Zend/zend_string.h:191 #1 0x55cfb941ceb6 in add_assoc_stringl_ex /work/php-src/Zend/zend_API.c:1986 #2 0x55cfb7f4c16d in add_assoc_stringl /work/php-src/Zend/zend_API.h:579 #3 0x55cfb7f4cccd in php_openssl_add_assoc_asn1_string /work/php-src/ext/openssl/openssl_backend_common.c:113 #4 0x55cfb7f2eb98 in zif_openssl_x509_parse /work/php-src/ext/openssl/openssl.c:1074 #5 0x55cfb9160993 in zend_test_execute_internal /work/php-src/ext/zend_test/observer.c:306 #6 0x55cfb958ee2d in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER /work/php-src/Zend/zend_vm_execute.h:2154 #7 0x55cfb97854bd in execute_ex /work/php-src/Zend/zend_vm_execute.h:116519 #8 0x55cfb9795c96 in zend_execute /work/php-src/Zend/zend_vm_execute.h:121962 #9 0x55cfb99666c6 in zend_execute_script /work/php-src/Zend/zend.c:1980 #10 0x55cfb919583e in php_execute_script_ex /work/php-src/main/main.c:2645 #11 0x55cfb9195b48 in php_execute_script /work/php-src/main/main.c:2685 #12 0x55cfb996bf48 in do_cli /work/php-src/sapi/cli/php_cli.c:951 #13 0x55cfb996e6a1 in main /work/php-src/sapi/cli/php_cli.c:1362 #14 0x7fb0b68301c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #15 0x7fb0b683028a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #16 0x55cfb7e097d4 in _start (/work/php-src/build-dbg-ubsan/sapi/cli/php+0x14097d4) (BuildId: b2b405964cc047ab6da19abaf92a8899a99e4a47) ``` Furthermore, it also simply does not propagate the error to userland. ClosesGH-21046.
This can actually fail because internally this function does stack management in internal data structures. Can cause a crash later, e.g.: ``` ==239255==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 0x5652d8f2fe68 bp 0x7ffc99ee8fc0 sp 0x7ffc99ee8ec0 T0) ==239255==The signal is caused by a READ memory access. ==239255==Hint: address points to the zero page. #0 0x5652d8f2fe68 in php_openssl_limit_handshake_reneg /work/php-src/ext/openssl/xp_ssl.c:1080 #1 0x5652d8f306e2 in php_openssl_info_callback /work/php-src/ext/openssl/xp_ssl.c:1137 #2 0x7f45057b84e5 (/lib/x86_64-linux-gnu/libssl.so.3+0x694e5) (BuildId: 5f3b12d47114f9fbdc7765266cd0bb8f1b5ee8fc) #3 0x5652d8f351d9 in php_openssl_enable_crypto /work/php-src/ext/openssl/xp_ssl.c:1850 #4 0x5652d8f39c86 in php_openssl_sockop_set_option /work/php-src/ext/openssl/xp_ssl.c:2516 #5 0x5652d9d4c610 in _php_stream_set_option /work/php-src/main/streams/streams.c:1466 #6 0x5652d9d557c1 in php_stream_xport_crypto_enable /work/php-src/main/streams/transports.c:387 #7 0x5652d8f387be in php_openssl_tcp_sockop_accept /work/php-src/ext/openssl/xp_ssl.c:2279 #8 0x5652d8f39fcd in php_openssl_sockop_set_option /work/php-src/ext/openssl/xp_ssl.c:2551 #9 0x5652d9d4c610 in _php_stream_set_option /work/php-src/main/streams/streams.c:1466 #10 0x5652d9d54d3a in php_stream_xport_accept /work/php-src/main/streams/transports.c:307 #11 0x5652d9b50161 in zif_stream_socket_accept /work/php-src/ext/standard/streamsfuncs.c:298 #12 0x5652d9fdacfb in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER /work/php-src/Zend/zend_vm_execute.h:1355 #13 0x5652da140689 in execute_ex /work/php-src/Zend/zend_vm_execute.h:116469 #14 0x5652da1558b0 in zend_execute /work/php-src/Zend/zend_vm_execute.h:121962 #15 0x5652da2ba0ab in zend_execute_script /work/php-src/Zend/zend.c:1980 #16 0x5652d9cec8bb in php_execute_script_ex /work/php-src/main/main.c:2645 #17 0x5652d9cecccb in php_execute_script /work/php-src/main/main.c:2685 #18 0x5652da2bfc16 in do_cli /work/php-src/sapi/cli/php_cli.c:951 #19 0x5652da2c21e3 in main /work/php-src/sapi/cli/php_cli.c:1362 #20 0x7f4504ebc1c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #21 0x7f4504ebc28a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #22 0x5652d8e09b34 in _start (/work/php-src/build-dbg-asan/sapi/cli/php+0x609b34) (BuildId: aa149f943514fff0c491e1f199e30fed0e977f7c) ``` ClosesGH-21049.
…dict ``` Direct leak of 52 byte(s) in 1 object(s) allocated from: #0 0x7ff90cd2c161 in malloc (/usr/lib/libasan.so.8+0x12c161) (BuildId: ee5fbab73143ab257a66a33afe0f038a4af7a74e) php#1 0x55de10c9a468 in tracked_malloc /work/php-8.4/Zend/zend_alloc.c:2973 php#2 0x55de10c99443 in _emalloc /work/php-8.4/Zend/zend_alloc.c:2740 php#3 0x55de102deb86 in zlib_create_dictionary_string /work/php-8.4/ext/zlib/zlib.c:836 php#4 0x55de102e145a in zif_deflate_init /work/php-8.4/ext/zlib/zlib.c:1144 php#5 0x55de10dcac6c in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /work/php-8.4/Zend/zend_vm_execute.h:1351 php#6 0x55de10f2d69d in execute_ex /work/php-8.4/Zend/zend_vm_execute.h:58907 php#7 0x55de10f41666 in zend_execute /work/php-8.4/Zend/zend_vm_execute.h:64334 php#8 0x55de110a6cf8 in zend_execute_script /work/php-8.4/Zend/zend.c:1934 php#9 0x55de10af0ddb in php_execute_script_ex /work/php-8.4/main/main.c:2577 php#10 0x55de10af128f in php_execute_script /work/php-8.4/main/main.c:2617 php#11 0x55de110ac5e1 in do_cli /work/php-8.4/sapi/cli/php_cli.c:935 php#12 0x55de110ae592 in main /work/php-8.4/sapi/cli/php_cli.c:1322 php#13 0x7ff90c027740 (/usr/lib/libc.so.6+0x27740) (BuildId: 020d6f7c33b2413f4fe10814c4729dce1387f049) php#14 0x7ff90c027878 in __libc_start_main (/usr/lib/libc.so.6+0x27878) (BuildId: 020d6f7c33b2413f4fe10814c4729dce1387f049) php#15 0x55de10005964 in _start (/work/php-8.4/sapi/cli/php+0x605964) (BuildId: 5f144db4e56ea623e070c56445fb1dfa3f8d085d) SUMMARY: AddressSanitizer: 52 byte(s) leaked in 1 allocation(s). ``` ClosesphpGH-22101.
…reset The code tries to read the context on NULL when `php_stream_xport_crypto_setup` fails because by then `stream` is reset to NULL. This is also UB, so can cause miscompiles. ``` ==1217==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000090 (pc 0x55d829ed3acf bp 0x7fff045f5770 sp 0x7fff045f4df0 T0) ==1217==The signal is caused by a READ memory access. ==1217==Hint: address points to the zero page. #0 0x55d829ed3acf in php_stream_url_wrap_http_ex /work/php-src/ext/standard/http_fopen_wrapper.c:580 #1 0x55d829ed857e in php_stream_url_wrap_http /work/php-src/ext/standard/http_fopen_wrapper.c:1204 #2 0x55d82a15073d in _php_stream_open_wrapper_ex /work/php-src/main/streams/streams.c:2270 #3 0x55d829e78fa6 in zif_file_get_contents /work/php-src/ext/standard/file.c:409 #4 0x55d829bbfe39 in zif_phar_file_get_contents /work/php-src/ext/phar/func_interceptors.c:226 #5 0x55d82a0b7ed2 in zend_test_execute_internal /work/php-src/ext/zend_test/observer.c:306 #6 0x55d82a3e024a in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER /work/php-src/Zend/zend_vm_execute.h:2154 #7 0x55d82a540995 in execute_ex /work/php-src/Zend/zend_vm_execute.h:116519 #8 0x55d82a5558b0 in zend_execute /work/php-src/Zend/zend_vm_execute.h:121962 #9 0x55d82a6ba0ab in zend_execute_script /work/php-src/Zend/zend.c:1980 #10 0x55d82a0ec8bb in php_execute_script_ex /work/php-src/main/main.c:2645 #11 0x55d82a0ecccb in php_execute_script /work/php-src/main/main.c:2685 #12 0x55d82a6bfc16 in do_cli /work/php-src/sapi/cli/php_cli.c:951 #13 0x55d82a6c21e3 in main /work/php-src/sapi/cli/php_cli.c:1362 #14 0x7f9e770491c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #15 0x7f9e7704928a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #16 0x55d829209b34 in _start (/work/php-src/build-dbg-asan/sapi/cli/php+0x609b34) (BuildId: aa149f943514fff0c491e1f199e30fed0e977f7c) ``` This is a backport of: * 7782b88 * f9519cc * afded3d Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
…reset The code tries to read the context on NULL when `php_stream_xport_crypto_setup` fails because by then `stream` is reset to NULL. This is also UB, so can cause miscompiles. ``` ==1217==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000090 (pc 0x55d829ed3acf bp 0x7fff045f5770 sp 0x7fff045f4df0 T0) ==1217==The signal is caused by a READ memory access. ==1217==Hint: address points to the zero page. #0 0x55d829ed3acf in php_stream_url_wrap_http_ex /work/php-src/ext/standard/http_fopen_wrapper.c:580 php#1 0x55d829ed857e in php_stream_url_wrap_http /work/php-src/ext/standard/http_fopen_wrapper.c:1204 php#2 0x55d82a15073d in _php_stream_open_wrapper_ex /work/php-src/main/streams/streams.c:2270 php#3 0x55d829e78fa6 in zif_file_get_contents /work/php-src/ext/standard/file.c:409 php#4 0x55d829bbfe39 in zif_phar_file_get_contents /work/php-src/ext/phar/func_interceptors.c:226 php#5 0x55d82a0b7ed2 in zend_test_execute_internal /work/php-src/ext/zend_test/observer.c:306 php#6 0x55d82a3e024a in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER /work/php-src/Zend/zend_vm_execute.h:2154 php#7 0x55d82a540995 in execute_ex /work/php-src/Zend/zend_vm_execute.h:116519 php#8 0x55d82a5558b0 in zend_execute /work/php-src/Zend/zend_vm_execute.h:121962 php#9 0x55d82a6ba0ab in zend_execute_script /work/php-src/Zend/zend.c:1980 php#10 0x55d82a0ec8bb in php_execute_script_ex /work/php-src/main/main.c:2645 php#11 0x55d82a0ecccb in php_execute_script /work/php-src/main/main.c:2685 php#12 0x55d82a6bfc16 in do_cli /work/php-src/sapi/cli/php_cli.c:951 php#13 0x55d82a6c21e3 in main /work/php-src/sapi/cli/php_cli.c:1362 php#14 0x7f9e770491c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) php#15 0x7f9e7704928a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) php#16 0x55d829209b34 in _start (/work/php-src/build-dbg-asan/sapi/cli/php+0x609b34) (BuildId: aa149f943514fff0c491e1f199e30fed0e977f7c) ``` This is a backport of: * 7782b88 * f9519cc * afded3d Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
The fix is in 3 commits. First, I enable a test that was skipped. Then I add a small feature to
zend_verify_arg_type(). The last commit modifies the 2 functions that were buggy,mb_substr()andmb_strcut(). The last commit message details the changes.I based my work on the branch PHP-5.4, but maybe this fix should be applied to an older version.