[php-src] Issue #24038: phpdbg: possible NULL dereference of `param` in `PHPDBG_LIST(lines)` when called from `PHPDBG_COMMAND(list)`

From: Date: Thu, 01 Oct 2026 08:13:33 +0000
Subject: [php-src] Issue #24038: phpdbg: possible NULL dereference of `param` in `PHPDBG_LIST(lines)` when called from `PHPDBG_COMMAND(list)`
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-252866@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/24038 Author: ushevchenko ### Description **Description** PHPDBG_COMMAND(list) in sapi/phpdbg/phpdbg_prompt.c explicitly handles param == NULL and passes it to the lines handler: ```c PHPDBG_COMMAND(list) /* {{{ */ { if (!param) { return PHPDBG_LIST_HANDLER(lines)(PHPDBG_COMMAND_ARGS); } else switch (param->type) { ... ``` PHPDBG_LIST(lines) in sapi/phpdbg/phpdbg_list.c then dereferences param without checking it: ```c PHPDBG_LIST(lines) /* {{{ */ { if (!PHPDBG_G(exec) && !zend_is_executing()) { phpdbg_error("Not executing, and execution context not set"); return SUCCESS; } switch (param->type) { ``` So the code contains a path where param is NULL and is dereferenced. The !param check in the caller shows that its author considered this state possible, while the callee does not handle it. **Reachability.** I did not reproduce a crash; this report is based on reading the code. The list command is registered with the argument specification "*", and phpdbg_internal_stack_execute() in phpdbg_cmd.c calls handler->handler(top) only if phpdbg_stack_verify() returned SUCCESS. For "*" the computed least is 1, so a call with no arguments fails with "expected at least ... arguments" before the handler runs. A search of sapi/phpdbg in master finds no direct call of PHPDBG_COMMAND_HANDLER(list), so PHPDBG_COMMAND(list) is reached only through this dispatcher. The !param branch therefore looks unreachable today. Other command handlers are invoked directly with a NULL parameter (for example, PHPDBG_COMMAND_HANDLER(run)(NULL) in phpdbg.c), so a NULL param is an expected convention in phpdbg, and PHPDBG_LIST(lines) is the one that does not handle it. If the dead branch is intentional, removing it (or an assertion documenting the contract) would also resolve this report. **Suggested fix** ```diff PHPDBG_LIST(lines) /* {{{ */ { + if (!param) { + phpdbg_error("A line number or file is required"); + return SUCCESS; + } + if (!PHPDBG_G(exec) && !zend_is_executing()) { ``` Found by Linux Verification Center (https://portal.linuxtesting.ru) using SVACE. Author U. Shevchenko. ### PHP Version ```plain 8.3.31 (static analysis of the source, not run); the same code is present in master ``` ### Operating System N/A (static analysis)

« previous php.bugs (#252866) next »