Skip to content

dba_open() can segfault for "pathless" streams #16390

Closed

Description

@YuanchengJiang

Description

The following code:

<?php
$file = 'data:text/plain;z=y;uri=eviluri;mediatype=wut?;mediatype2=hello,somedata';
$fusion = $file;
$db = dba_open($fusion, 'c', 'inifile');

Resulted in this output:

/php-src/ext/dba/dba.c:845: void php_dba_open(zend_execute_data *, zval *, _Bool): Assertion `opened_path' failed.
Aborted (core dumped)

PHP Version

nightly

Operating System

ubuntu 22.04

Activity

  1. ndossche commented on Oct 12, 2024

    @ndossche
    Member

    php-src/ext/dba/dba.c

    Lines 845 to 848 in 8953348

    ZEND_ASSERT(opened_path);
    /* replace the path info with the real path of the opened file */
    zend_string_release_ex(connection->info->path, persistent);
    connection->info->path = php_dba_zend_string_dup_safe(opened_path, persistent);

    /* replace the path info with the real path of the opened file */

    But we don't have a real path...

  2. cmb69 commented on Oct 17, 2024

    @cmb69
    Member

    Maybe

     ext/dba/dba.c | 11 +++++++----
     1 file changed, 7 insertions(+), 4 deletions(-)
    
    diff --git a/ext/dba/dba.c b/ext/dba/dba.c
    index 04cee6f385..2bd0c8292a 100644
    --- a/ext/dba/dba.c
    +++ b/ext/dba/dba.c
    @@ -842,10 +842,13 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
     			connection->info->lock.fp = php_stream_open_wrapper(lock_name, lock_file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|persistent_flag, &opened_path);
     			if (connection->info->lock.fp) {
     				if (is_db_lock) {
    -					ZEND_ASSERT(opened_path);
    -					/* replace the path info with the real path of the opened file */
    -					zend_string_release_ex(connection->info->path, persistent);
    -					connection->info->path = php_dba_zend_string_dup_safe(opened_path, persistent);
    +					if (opened_path) {
    +						/* replace the path info with the real path of the opened file */
    +						zend_string_release_ex(connection->info->path, persistent);
    +						connection->info->path = php_dba_zend_string_dup_safe(opened_path, persistent);
    +					} else {
    +						zend_argument_error(…);
    +					}
     				}
     			}
     			if (opened_path) {

    By the way, a couple of lines below we have

    php-src/ext/dba/dba.c

    Lines 865 to 870 in 3351dae

    if (!php_stream_supports_lock(connection->info->lock.fp)) {
    error = "Stream does not support locking";
    }
    if (php_stream_lock(connection->info->lock.fp, lock_mode)) {
    error = "Unable to establish lock"; /* force failure exit */
    }

    It's rather unlikely that the first error message will ever show up.

  3. ndossche commented on Oct 17, 2024

    @ndossche
    Member

    Right, the patch idea makes sense.

  4. self-assigned this
    on Oct 18, 2024
  5. added a commit that references this issue on Oct 18, 2024
    47e9c1e
  6. changed the title [-]Assertion failure in ext/dba/dba.c:845[/-] [+]dba_open() can segfault for "pathless" streams[/+] on Oct 18, 2024
  7. added 2 commits that reference this issue on Oct 20, 2024
    d3b0efe
    e635857
  8. added 2 commits that reference this issue on Oct 20, 2024
    2c0fd88
    514c2b3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions