[php-src] Issue #24372: PHP 8.6.0RC3: crash in pecl pdo_oci when doing execute()+fetch_all() twice using the same prepared statement
| From: | rainerjung | Date: | Fri, 16 Oct 2026 10:58:36 +0000 |
| Subject: | [php-src] Issue #24372: PHP 8.6.0RC3: crash in pecl pdo_oci when doing execute()+fetch_all() twice using the same prepared statement | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-253006@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/24372
Author: rainerjung
### Description
Platform: Linux x64 (Alma 9 and 10)
PHP-Version: PHP 8.6.0RC3 but not (!!) happening for PHP 8.6.0RC2
pdo_oci: version 1.2.0 plus small patch from https://github.com/php/pecl-database-pdo_oci/pull/41
PHP script showing the crash:
```
<?php
$dsn =
'oci:dbname=(DESCRIPTION=(ADDRESS=(HOST=myhost)(PROTOCOL=tcp)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=mydb)))';
$user = 'myuser';
$pass = 'mypass';
$db = PDO::connect($dsn, $user, $pass, null);
if (!$db) {
die("Could not create PDO object (DSN=$dsn, user=$user)\n");
}
// Next two lines only needed for first use of this script
$db->exec('CREATE TABLE testtable(id CHAR(1) NOT NULL PRIMARY KEY, val CHAR(1))');
$db->exec("INSERT INTO testtable VALUES('A', 'B')");
$stmt = $db->prepare('SELECT id, val from testtable');
echo "Before first execution...\n";
$stmt->execute();
echo "Before first fetch...\n";
var_dump($stmt->fetchAll());
echo "Before second execution...\n";
$stmt->execute();
echo "Before second fetch...\n";
var_dump($stmt->fetchAll());
?>
```
Execution with "php -d extension=pdo -d extension=pdo_oci myscript.php"
RC2 succeeds:
```
Before first fetch...
array(1) {
[0]=>
array(4) {
["ID"]=>
string(1) "A"
[0]=>
string(1) "A"
["VAL"]=>
string(1) "B"
[1]=>
string(1) "B"
}
}
Before second execution...
Before second fetch...
array(1) {
[0]=>
array(4) {
["ID"]=>
string(1) "A"
[0]=>
string(1) "A"
["VAL"]=>
string(1) "B"
[1]=>
string(1) "B"
}
}
```
RC3 fails with segfault crash:
```
Before first execution...
Before first fetch...
array(1) {
[0]=>
array(4) {
["ID"]=>
string(1) "A"
[0]=>
string(1) "A"
["VAL"]=>
string(1) "B"
[1]=>
string(1) "B"
}
}
Before second execution...
Before second fetch...
Segmentation fault (core dumped)
```
During the fetch a column gets a string of length 1 but with string pointer NULL, so creating a
ZSTR_CHAR from it crashes when trying to dereference the first character in this string.
Stack:
```
#0 0x00007f8e348a8a74 in __pthread_kill_implementation () from /lib64/libc.so.6
#1 0x00007f8e3484f37e in raise () from /lib64/libc.so.6
#2 0x00007f8e331665c4 in skgesigOSCrash () from
/path/to/oracle-instantclient/12.1.0.2.0.linux.x86_64/libclntsh.so.12.1
#3 0x00007f8e3343dde6 in kpeDbgSignalHandler () from
/path/to/oracle-instantclient/12.1.0.2.0.linux.x86_64/libclntsh.so.12.1
#4 0x00007f8e331667b5 in skgesig_sigactionHandler () from
/path/to/oracle-instantclient/12.1.0.2.0.linux.x86_64/libclntsh.so.12.1
#5 <signal handler called>
#6 ZSTR_CHAR (c=<error reading variable: Cannot access memory at address 0x0>)
at /path/to/include/php/Zend/zend_string.h:119
#7 zend_string_init_fast (str=0x0, len=1) at /path/to/include/php/Zend/zend_string.h:226
#8 oci_stmt_get_col (stmt=0x7f8e34694000, colno=0, result=0x7ffd35b48580, type=0x0)
at /path/to/pecl-database-pdo_oci-1.2.0/oci_statement.c:810
#9 0x00007f8e34595554 in fetch_value (stmt=stmt@entry=0x7f8e34694000,
dest=dest@entry=0x7ffd35b48580, colno=colno@entry=0, type_override=type_override@entry=0x0)
at /path/to/php86/ext/pdo/pdo_stmt.c:535
#10 0x00007f8e34597f6d in do_fetch (stmt=stmt@entry=0x7f8e34694000,
return_value=return_value@entry=0x7ffd35b48620, how=PDO_FETCH_BOTH,
ori=ori@entry=PDO_FETCH_ORI_NEXT,
offset=offset@entry=0, group_key=group_key@entry=0x0) at /path/to/php86/ext/pdo/pdo_stmt.c:883
#11 0x00007f8e34598e53 in zim_PDOStatement_fetchAll (execute_data=<optimized out>,
return_value=0x7f8e346141d0)
at /path/to/php86/ext/pdo/pdo_stmt.c:1322
#12 0x00007f8e350d9139 in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER () at
/path/to/php86/Zend/zend_vm_execute.h:2152
#13 execute_ex (ex=0x7f8e34694000) at /path/to/php86/Zend/zend_vm_execute.h:110852
#14 0x00007f8e350ce875 in zend_execute (op_array=op_array@entry=0x7f8e34693300,
return_value=return_value@entry=0x0)
at /path/to/php86/Zend/zend_vm_execute.h:116021
#15 0x00007f8e3513adf0 in zend_execute_script (type=type@entry=8, retval=retval@entry=0x0,
file_handle=file_handle@entry=0x7ffd35b4ac10)
at /path/to/php86/Zend/zend.c:1980
#16 0x00007f8e34fcb9c6 in php_execute_script_ex (primary_file=<optimized out>,
retval=retval@entry=0x0)
at /path/to/php86/main/main.c:2605
#17 0x00007f8e34fcbcc7 in php_execute_script (primary_file=<optimized out>) at
/path/to/php86/main/main.c:2645
#18 0x00000000006026ab in do_cli (argc=argc@entry=6, argv=argv@entry=0x182e6300) at
/path/to/php86/sapi/cli/php_cli.c:943
#19 0x0000000000602cde in do_php_cli (argc=6, argv=0x182e6300) at
/path/to/php86/sapi/cli/php_cli.c:1356
#20 0x00007f8e34838348 in __libc_start_call_main () from /lib64/libc.so.6
#21 0x00007f8e3483840b in __libc_start_main_impl () from /lib64/libc.so.6
#22 0x0000000000600b95 in _start ()
```
Stack with variable info:
```
#6 ZSTR_CHAR (c=<error reading variable: Cannot access memory at address 0x0>)
at /path/to/include/php/Zend/zend_string.h:119
No locals.
#7 zend_string_init_fast (str=0x0, len=1) at /path/to/include/php/Zend/zend_string.h:226
No locals.
#8 oci_stmt_get_col (stmt=0x7f8e34694000, colno=0, result=0x7ffd35b48580, type=0x0)
at /path/to/pecl-database-pdo_oci-1.2.0/oci_statement.c:810
__z = 0x7ffd35b48580
__s = <optimized out>
S = 0x7f8e346810a0
C = 0x7f8e3468c080
#9 0x00007f8e34595554 in fetch_value (stmt=stmt@entry=0x7f8e34694000,
dest=dest@entry=0x7ffd35b48580, colno=colno@entry=0, type_override=type_override@entry=0x0)
at /path/to/ext/pdo/pdo_stmt.c:535
pdo_param_str = PDO_PARAM_NULL
#10 0x00007f8e34597f6d in do_fetch (stmt=stmt@entry=0x7f8e34694000,
return_value=return_value@entry=0x7ffd35b48620, how=PDO_FETCH_BOTH,
ori=ori@entry=PDO_FETCH_ORI_NEXT,
offset=offset@entry=0, group_key=group_key@entry=0x0) at /path/to/ext/pdo/pdo_stmt.c:883
val = {value = {lval = 140248741350496, dval = 6.9292084973754746e-310, counted =
0x7f8e34688c60, str = 0x7f8e34688c60, arr = 0x7f8e34688c60, obj = 0x7f8e34688c60,
res = 0x7f8e34688c60, ref = 0x7f8e34688c60, ast = 0x7f8e34688c60, zv = 0x7f8e34688c60,
ptr = 0x7f8e34688c60, ce = 0x7f8e34688c60, func = 0x7f8e34688c60, ww = {
w1 = 879266912, w2 = 32654}}, u1 = {type_info = 1, v = {type = 1 '\001',
type_flags = 0 '\000', u = {extra = 0}}}, u2 = {next = 32654, cache_slot = 32654,
opline_num = 32654, lineno = 32654, num_args = 32654, fe_pos = 32654, fe_iter_idx =
32654, guard = 32654, constant_flags = 32654, extra = 32654}}
column_name = <optimized out>
flags = 0
ce = <optimized out>
ctor_arguments = <optimized out>
column_index_to_fetch = 0
fetch_function_params = <optimized out>
fetch_function_param_num = 0
#11 0x00007f8e34598e53 in zim_PDOStatement_fetchAll (execute_data=<optimized out>,
return_value=0x7f8e346141d0)
at /path/to/ext/pdo/pdo_stmt.c:1322
how = 4
arg2 = <optimized out>
old_ce = <optimized out>
old_ctor_args = <optimized out>
ctor_args = <optimized out>
stmt = 0x7f8e34694000
fetch_mode = <optimized out>
flags = 0
data = {value = {lval = 140248741151448, dval = 6.9292084875411968e-310, counted =
0x7f8e346582d8, str = 0x7f8e346582d8, arr = 0x7f8e346582d8, obj = 0x7f8e346582d8,
res = 0x7f8e346582d8, ref = 0x7f8e346582d8, ast = 0x7f8e346582d8, zv = 0x7f8e346582d8,
ptr = 0x7f8e346582d8, ce = 0x7f8e346582d8, func = 0x7f8e346582d8, ww = {
w1 = 879067864, w2 = 32654}}, u1 = {type_info = 775, v = {type = 7 '\a',
type_flags = 3 '\003', u = {extra = 0}}}, u2 = {next = 32654, cache_slot = 32654,
opline_num = 32654, lineno = 32654, num_args = 32654, fe_pos = 32654, fe_iter_idx =
32654, guard = 32654, constant_flags = 32654, extra = 32654}}
group_key = {value = {lval = 0, dval = 0, counted = 0x0, str = 0x0, arr = 0x0, obj = 0x0,
res = 0x0, ref = 0x0, ast = 0x0, zv = 0x0, ptr = 0x0, ce = 0x0, func = 0x0,
ww = {w1 = 0, w2 = 0}}, u1 = {type_info = 407588640, v = {type = 32 ' ',
type_flags = 79 'O', u = {extra = 6219}}}, u2 = {next = 0, cache_slot = 0,
opline_num = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0, guard = 0,
constant_flags = 0, extra = 0}}
#12 0x00007f8e350d9139 in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER () at
/path/to/Zend/zend_vm_execute.h:2152
call = 0x7f8e34614250
fbc = 0x184b4f20
ret = <optimized out>
retval = <optimized out>
no_discard = <optimized out>
call = <optimized out>
fbc = <optimized out>
ret = <optimized out>
retval = <optimized out>
no_discard = <optimized out>
#13 execute_ex (ex=0x7f8e34694000) at /path/to/Zend/zend_vm_execute.h:110852
```
Here's more info about the data in oci_stmt_get_col():
```
(gdb) print *stmt
$3 = {methods = 0x7f8e3480cce0 <oci_stmt_methods>, driver_data = 0x7f8e346810a0, error_code =
"00000", executed = 1, in_fetch = 1, supports_placeholders = 1,
in_param_event = 0, reserved = 0, bound_params = 0x0, bound_param_map = 0x0, bound_columns = 0x0,
columns = 0x7f8e34602450, column_count = 2,
default_fetch_type = PDO_FETCH_BOTH, fetch = {column = 0, cls = {ctor_args = 0x0, ce = 0x0}, func
= {fcc = {function_handler = 0x0, calling_scope = 0x0, called_scope = 0x0,
object = 0x0, closure = 0x0}}, into = 0x0}, lazy_object_ref = 0x0, dbh = 0x7f8e34659140,
database_object_handle = 0x7f8e346023c8, row_count = 0,
query_string = 0x7f8e34658380, active_query_string = 0x0, named_rewrite_template = 0x0, std = {gc
= {refcount = 2, u = {type_info = 3221227528}}, handle = 2,
extra_flags = 0, ce = 0x184b1f90, handlers = 0x7f8e345a6860 <pdo_dbstmt_object_handlers>,
properties = 0x0, properties_table = {{value = {lval = 140248741151616,
dval = 6.9292084875494971e-310, counted = 0x7f8e34658380, str = 0x7f8e34658380, arr =
0x7f8e34658380, obj = 0x7f8e34658380, res = 0x7f8e34658380,
ref = 0x7f8e34658380, ast = 0x7f8e34658380, zv = 0x7f8e34658380, ptr = 0x7f8e34658380, ce
= 0x7f8e34658380, func = 0x7f8e34658380, ww = {w1 = 879068032,
w2 = 32654}}, u1 = {type_info = 6, v = {type = 6 '\006', type_flags = 0
'\000', u = {extra = 0}}}, u2 = {next = 0, cache_slot = 0, opline_num = 0, lineno = 0,
num_args = 0, fe_pos = 0, fe_iter_idx = 0, guard = 0, constant_flags = 0, extra = 0}}}}}
(gdb) print *S
$1 = {H = 0x7f8e34682060, stmt = 0x1858a060, err = 0x185888a0, last_err = 0, stmt_type = 1,
exec_type = 0, cols = 0x7f8e3468c080, einfo = {
file = 0x7f8e3480a710 "/path/to/pecl-database-pdo_oci-1.2.0/oci_statement.c", line =
197, errcode = 0, errmsg = 0x0},
have_blobs = 0}
(gdb) print *C
$5 = {def = 0x0, fetched_len = 1, retcode = 0, indicator = 0, data = 0x0, datalen = 0, dtype = 0}
```
Here's more info about the data in do_fetch():
```
(gdb) print how
$14 = PDO_FETCH_BOTH
(gdb) print ori
$15 = PDO_FETCH_ORI_NEXT
(gdb) print offset
$16 = 0
(gdb) print group_key
$17 = (zval *) 0x0
```
### PHP Version
```plain
PHP 8.6.0RC3 (cli) (built: Oct 14 2026 18:13:21) (NTS)
Copyright © The PHP Group and Contributors
Zend Engine v4.6.0RC3, Copyright © Zend by Perforce
with Zend OPcache v8.6.0RC3, Copyright ©, by Zend by Perforce
```
### Operating System
AlmaLinux 10 (also happens on Alma 9)