Skip to content

Io\Poll\Context::wait() prevent integer overflow - #23468

Open
marc-mabe wants to merge 1 commit into
php:masterfrom
marc-mabe:poll_max_events
Open

Io\Poll\Context::wait() prevent integer overflow#23468
marc-mabe wants to merge 1 commit into
php:masterfrom
marc-mabe:poll_max_events

Conversation

@marc-mabe

@marc-mabe marc-mabe commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

This prevents integer overflow in case of SIZEOF_INT < SIZEOF_ZEND_LONG

Comment thread ext/standard/tests/poll/poll_wait_error_max_events.phpt Outdated
@devnexen

devnexen commented Aug 26, 2026

Copy link
Copy Markdown
Member

Hi @marc-mabe ; overflow check is safe_emalloc job here, so it s basically all about getting a tailored error message ?Not sure it s worth it honestly. Other unwarranted changes I see as well as variables declarations, we moved away from iso 90 a while ago.

Comment thread ext/standard/io_poll.c Outdated
}
} else if (max_events <= 0) {
zend_argument_value_error(2, "must be greater than 0");
} else if (UNEXPECTED(max_events <= 0 || max_events > MIN(INT_MAX, SIZE_MAX / sizeof(*events) - 4096))) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I m not sure the upper range check is correct/relevant on 64 bits anyway.

@marc-mabe marc-mabe Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@devnexen max_events is limited by two things:

  1. int cast
  2. size_t memory allocation

The int cast is the problematic one.
I came to these lines while working on #19079 where size_t matters as well but as it's limited by the int cast I thought this is something that should be handled unrelated to to the work in #19079 - so I created this PR.

I'll update this PR to checking for max_events > INT_MAX only.

Hope it makes more sense now.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright can we also have a test along these lines ?

--TEST--
  Io\Poll\Context::wait(): Parameter validation
  --FILE--
  <?php
  require_once __DIR__ . '/poll.inc';

  $poll_ctx = new Io\Poll\Context();

  try {
      $poll_ctx->wait(timeout: Time\Duration::fromSeconds(1)->negate());
  } catch (Throwable $e) {
      echo $e::class, ': ', $e->getMessage(), PHP_EOL;
  }

  try {
      $poll_ctx->wait(maxEvents: -1);
  } catch (Throwable $e) {
      echo $e::class, ': ', $e->getMessage(), PHP_EOL;
  }

  try {
      $poll_ctx->wait(maxEvents: 0);
  } catch (Throwable $e) {
      echo $e::class, ': ', $e->getMessage(), PHP_EOL;
  }

  try {
      $poll_ctx->wait(maxEvents: PHP_INT_MAX);
  } catch (Throwable $e) {
      echo $e::class, ': ', $e->getMessage(), PHP_EOL;
  }

  var_dump($poll_ctx->wait(Time\Duration::fromSeconds(0), 64));

  ?>
  --EXPECTF--
  ValueError: Io\Poll\Context::wait(): Argument #1 ($timeout) must not
  ValueError: Io\Poll\Context::wait(): Argument #2 ($maxEvents) must be greater than 0
  ValueError: Io\Poll\Context::wait(): Argument #2 ($maxEvents) must be greater than 0
  ValueError: Io\Poll\Context::wait(): Argument #2 ($maxEvents) must be less than or equal to %d
  array(0) {
  }

@marc-mabe marc-mabe changed the title Io\Poll\Context::wait() max events range check Io\Poll\Context::wait() prevent integer overflow Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants