Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

realloc with size 0 in user_filters.c #17650

Open
chongwick opened this issue Jan 31, 2025 · 0 comments · May be fixed by #17656
Open

realloc with size 0 in user_filters.c #17650

chongwick opened this issue Jan 31, 2025 · 0 comments · May be fixed by #17656

Comments

@chongwick
Copy link

Description

The following code:

<?php
class testfilter extends php_user_filter {
  function filter($in, $out, &$consumed, $closing): int {
    while ($bucket = stream_bucket_make_writeable($in)) {
      $bucket->data = preg_replace('/.(?<!^)/m', '', strtoupper($bucket->data));
      $consumed += strlen($bucket->data);
      stream_bucket_append($out, $bucket);
    }
    return PSFS_PASS_ON;
  }

  function oncreate(): bool {
    echo "params: {$this->params}\n";
    return true;
  }
}

stream_filter_register('testfilter','testfilter');

$text = "Hello There!";

$fp = tmpfile();
fwrite($fp, $text);

rewind($fp);
stream_filter_append($fp, 'testfilter', STREAM_FILTER_READ, 'testuserfilter');

while ($line = fgets($fp)) {
    assertArrayEquals(["Hello"], explode(" ", $line));
}

fclose($fp);

Resulted in this output:

php-src/ext/standard/user_filters.c:408:3: runtime error: null pointer passed as argument 1, which is declared to never be null

USE_ZEND_ALLOC=0 php test.php

PHP Version

nightly

Operating System

ubuntu 22.04

@nielsdos nielsdos changed the title invalid memory usage in user_filters.c realloc with size 0 user_filters.c Jan 31, 2025
@nielsdos nielsdos changed the title realloc with size 0 user_filters.c realloc with size 0 in user_filters.c Jan 31, 2025
nielsdos added a commit to nielsdos/php-src that referenced this issue Jan 31, 2025
If the returned buffer string is of length 0, then a realloc can happen
with length 0. However, the behaviour is implementation-defined.
From 7.20.3.1 of C11 spec:

> If the size of the space requested is zero, the behavior is
> implementation-defined: either a null pointer is returned,
> or the behavior is as if the size were some nonzero value,
> except that the returned pointer shall not be used to access an object

This is problematic for the test case on my system as it returns NULL,
causing a memleak and later using it in memcpy causing UB.
The bucket code is not prepared to handle a NULL pointer.
To solve this, we use MAX to clamp the size to 1 at the least.
@nielsdos nielsdos linked a pull request Jan 31, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants